You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by to...@apache.org on 2015/03/07 00:10:37 UTC
[3/4] incubator-usergrid git commit: Added caching to org/app lookup
Added caching to org/app lookup
Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/4c8727c1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/4c8727c1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/4c8727c1
Branch: refs/heads/USERGRID-416
Commit: 4c8727c1dc0e5f02a498849be1a19e6342f6accf
Parents: 2c54a2b
Author: Todd Nine <tn...@apigee.com>
Authored: Fri Mar 6 15:13:49 2015 -0700
Committer: Todd Nine <tn...@apigee.com>
Committed: Fri Mar 6 15:13:49 2015 -0700
----------------------------------------------------------------------
.../corepersistence/CpEntityManager.java | 1 +
.../corepersistence/CpEntityManagerFactory.java | 116 ++++--------
.../corepersistence/OrgApplicationCache.java | 67 +++++++
.../OrgApplicationCacheImpl.java | 181 +++++++++++++++++++
.../main/resources/usergrid-core-context.xml | 14 +-
.../persistence/index/EntityIndexFactory.java | 4 +-
.../resources/usergrid-services-context.xml | 8 +-
7 files changed, 296 insertions(+), 95 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/4c8727c1/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
index 5619382..652e084 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
@@ -676,6 +676,7 @@ public class CpEntityManager implements EntityManager {
@Override
public RelationManager getRelationManager( EntityRef entityRef ) {
+ Preconditions.checkNotNull( entityRef, "entityRef cannot be null" );
CpRelationManager rmi = new CpRelationManager();
rmi.init( this, emf, applicationId, entityRef, null );
return rmi;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/4c8727c1/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java
index 9aa36a0..16de53e 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManagerFactory.java
@@ -15,6 +15,7 @@
*/
package org.apache.usergrid.corepersistence;
+import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
@@ -98,6 +99,8 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
}
});
+ private final OrgApplicationCache orgApplicationCache;
+
private ManagerCache managerCache;
private DataMigrationManager dataMigrationManager;
@@ -116,7 +119,7 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
this.managerCache = injector.getInstance( ManagerCache.class );
this.dataMigrationManager = injector.getInstance( DataMigrationManager.class );
-
+ this.orgApplicationCache = new OrgApplicationCacheImpl( this );
}
@@ -156,18 +159,6 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
}
-// public ManagerCache getManagerCache() {
-//
-// if ( managerCache == null ) {
-// managerCache = injector.getInstance( ManagerCache.class );
-//
-// dataMigrationManager = injector.getInstance( DataMigrationManager.class );
-// }
-// return managerCache;
-// }
-
-
-
@Override
public EntityManager getEntityManager(UUID applicationId) {
try {
@@ -207,15 +198,16 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
String appName = buildAppName( orgName, name );
- UUID applicationId = lookupApplication( appName );
- if ( applicationId != null ) {
+ final Optional<UUID> appId = orgApplicationCache.getApplicationId( appName );
+
+ if ( appId.isPresent() ) {
throw new ApplicationAlreadyExistsException( name );
}
- applicationId = UUIDGenerator.newTimeUUID();
+ UUID applicationId = UUIDGenerator.newTimeUUID();
- logger.debug( "New application orgName {} name {} id {} ",
+ logger.debug( "New application orgName {} orgAppName {} id {} ",
new Object[] { orgName, name, applicationId.toString() } );
initializeApplication( orgName, applicationId, appName, properties );
@@ -233,6 +225,10 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
Map<String, Object> properties ) throws Exception {
+
+ //Ensure our management system exists before creating our application
+ init();
+
EntityManager em = getEntityManager( CpNamingUtils.SYSTEM_APP_ID);
final String appName = buildAppName( organizationName, name );
@@ -244,8 +240,14 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
getSetup().setupApplicationKeyspace( applicationId, appName );
- UUID orgUuid = lookupOrganization( organizationName );
- if ( orgUuid == null ) {
+
+ final Optional<UUID> cachedValue = orgApplicationCache.getOrganizationId( name );
+
+
+ final UUID orgUuid;
+
+ if ( !cachedValue.isPresent() ) {
+
// create new org because the specified one does not exist
final String orgName = organizationName;
@@ -263,6 +265,11 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
em.refreshIndex();
orgUuid = orgInfo.getUuid();
+
+ //evit so it's re-loaded later
+ orgApplicationCache.evictOrgId( name );
+ } else{
+ orgUuid = cachedValue.get();
}
// create appinfo entry in the system app
@@ -293,6 +300,10 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
appEm.refreshIndex();
logger.info("Initialized application {}", appName );
+
+ //evict app Id from cache
+ orgApplicationCache.evictAppId( appName );
+
return applicationId;
}
@@ -374,71 +385,10 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
}
- public UUID lookupOrganization( String name ) throws Exception {
- init();
-
-
- // Query q = Query.fromQL(PROPERTY_NAME + " = '" + name + "'");
- EntityManager em = getEntityManager( CpNamingUtils.SYSTEM_APP_ID );
-
-
- final EntityRef alias = em.getAlias( "organizations", name );
-
- if ( alias == null ) {
- return null;
- }
-
- final Entity entity = em.get( alias );
-
- if ( entity == null ) {
- return null;
- }
-
- return entity.getUuid();
- // Results results = em.searchCollection( em.getApplicationRef(), "organizations", q );
- //
- // if ( results.isEmpty() ) {
- // return null;
- // }
- //
- // return results.iterator().next().getUuid();
- }
-
@Override
- public UUID lookupApplication( String name ) throws Exception {
- init();
-
- // TODO: why does this not work for restored apps
-
-// EntityManager em = getEntityManager( CpNamingUtils.SYSTEM_APP_ID );
-// final EntityRef alias = em.getAlias( CpNamingUtils.APPINFOS, name );
-// if ( alias == null ) {
-// return null;
-// }
-// final Entity entity = em.get( alias );
-// if ( entity == null ) {
-// return null;
-// }
-// final UUID property = ( UUID ) entity.getProperty( "applicationUuid" );
-// return property;
-
- Query q = Query.fromQL( PROPERTY_NAME + " = '" + name + "'");
-
- EntityManager em = getEntityManager(CpNamingUtils.SYSTEM_APP_ID);
-
- Results results = em.searchCollection( em.getApplicationRef(), "appinfos", q);
-
- if ( results.isEmpty() ) {
- return null;
- }
-
- Entity entity = results.iterator().next();
- Object uuidObject = entity.getProperty("applicationUuid");
- if ( uuidObject instanceof UUID ) {
- return (UUID)uuidObject;
- }
- return UUIDUtils.tryExtractUUID( entity.getProperty("applicationUuid").toString() );
+ public UUID lookupApplication( String orgAppName ) throws Exception {
+ return orgApplicationCache.getApplicationId( orgAppName ).orNull();
}
@@ -632,7 +582,7 @@ public class CpEntityManagerFactory implements EntityManagerFactory, Application
em.update( propsEntity );
} catch (Exception ex) {
- logger.error("Error deleting service property name: " + name, ex);
+ logger.error("Error deleting service property orgAppName: " + name, ex);
return false;
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/4c8727c1/stack/core/src/main/java/org/apache/usergrid/corepersistence/OrgApplicationCache.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/OrgApplicationCache.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/OrgApplicationCache.java
new file mode 100644
index 0000000..b20dbe1
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/OrgApplicationCache.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.usergrid.corepersistence;
+
+
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.Entity;
+
+import com.google.common.base.Optional;
+
+
+/**
+ * A simple cache interface for looking up entities from an EM
+ */
+public interface OrgApplicationCache {
+
+
+ /**
+ * Get an entity by it's alias property. The result is cached. To clear it call evict or evict all
+ * @param
+ * @return
+ */
+ public Optional<UUID> getOrganizationId(final String orgName);
+
+ /**
+ * Evict the org by name
+ * @param orgName
+ */
+ public void evictOrgId(final String orgName);
+
+ /**
+ * Evict the application by name
+ * @param applicationName
+ * @return
+ */
+ public Optional<UUID> getApplicationId(final String applicationName);
+
+
+ /**
+ * Evict the app id by the name
+ */
+ public void evictAppId(final String applicationname);
+
+
+ /**
+ * Evict all caches
+ */
+ public void evictAll();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/4c8727c1/stack/core/src/main/java/org/apache/usergrid/corepersistence/OrgApplicationCacheImpl.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/OrgApplicationCacheImpl.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/OrgApplicationCacheImpl.java
new file mode 100644
index 0000000..4baf598
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/OrgApplicationCacheImpl.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.usergrid.corepersistence;
+
+
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import org.apache.usergrid.corepersistence.util.CpNamingUtils;
+import org.apache.usergrid.persistence.Entity;
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.EntityManagerFactory;
+import org.apache.usergrid.persistence.EntityRef;
+import org.apache.usergrid.persistence.Results;
+import org.apache.usergrid.persistence.index.query.Query;
+import org.apache.usergrid.utils.UUIDUtils;
+
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+import static org.apache.usergrid.persistence.Schema.PROPERTY_NAME;
+
+
+/**
+ * Implements the org app cache for faster runtime lookups. These values are immutable, so this LRU cache can stay
+ * full for the duration of the execution
+ */
+public class OrgApplicationCacheImpl implements OrgApplicationCache {
+
+
+ /**
+ * Cache the pointer to our root entity manager for reference
+ */
+ private final EntityManager rootEm;
+
+ private final LoadingCache<String, Optional<UUID>> orgCache =
+ CacheBuilder.newBuilder().maximumSize( 10000 ).build( new CacheLoader<String, Optional<UUID>>() {
+ @Override
+ public Optional<UUID> load( final String key ) throws Exception {
+ return fetchOrganizationId( key );
+ }
+ } );
+
+
+ private final LoadingCache<String, Optional<UUID>> appCache =
+ CacheBuilder.newBuilder().maximumSize( 10000 ).build( new CacheLoader<String, Optional<UUID>>() {
+ @Override
+ public Optional<UUID> load( final String key ) throws Exception {
+ return fetchApplicationId( key );
+ }
+ } );
+
+
+ public OrgApplicationCacheImpl( final EntityManagerFactory emf ) {
+ this.rootEm = emf.getEntityManager( CpNamingUtils.SYSTEM_APP_ID );
+ }
+
+
+ @Override
+ public Optional<UUID> getOrganizationId( final String orgName ) {
+ try {
+ return orgCache.get( orgName );
+ }
+ catch ( ExecutionException e ) {
+ throw new RuntimeException( "Unable to load org cache", e );
+ }
+ }
+
+
+ /**
+ * Fetches the organization
+ */
+ private Optional<UUID> fetchOrganizationId( final String orgName ) {
+
+ try {
+ final EntityRef alias = rootEm.getAlias( "organizations", orgName );
+
+ if ( alias == null ) {
+ return Optional.absent();
+ }
+
+ final Entity entity;
+
+ entity = rootEm.get( alias );
+
+
+ if ( entity == null ) {
+ return Optional.absent();
+ }
+
+ return Optional.of( entity.getUuid() );
+ }
+ catch ( Exception e ) {
+ throw new RuntimeException( "Unable to load organization Id for caching", e );
+ }
+ }
+
+
+ @Override
+ public void evictOrgId( final String orgName ) {
+ orgCache.invalidate( orgName );
+ }
+
+
+ @Override
+ public Optional<UUID> getApplicationId( final String applicationName ) {
+ try {
+ return appCache.get( applicationName );
+ }
+ catch ( ExecutionException e ) {
+ throw new RuntimeException( "Unable to load org cache", e );
+ }
+ }
+
+
+ /**
+ * Fetch our application id
+ */
+ private Optional<UUID> fetchApplicationId( final String applicationName ) {
+
+ try {
+ Query q = Query.fromQL( PROPERTY_NAME + " = '" + applicationName + "'" );
+
+
+ Results results = rootEm.searchCollection( rootEm.getApplicationRef(), "appinfos", q );
+
+ if ( results.isEmpty() ) {
+ return Optional.absent();
+ }
+
+ Entity entity = results.iterator().next();
+ Object uuidObject = entity.getProperty( "applicationUuid" );
+
+ final UUID value;
+ if ( uuidObject instanceof UUID ) {
+ value = ( UUID ) uuidObject;
+ }
+ else {
+ value = UUIDUtils.tryExtractUUID( entity.getProperty( "applicationUuid" ).toString() );
+ }
+
+
+ return Optional.of( value );
+ }
+ catch ( Exception e ) {
+ throw new RuntimeException( "Unable to retreive application id", e );
+ }
+ }
+
+
+ @Override
+ public void evictAppId( final String applicationName ) {
+ appCache.invalidate( applicationName );
+ }
+
+
+ @Override
+ public void evictAll() {
+ orgCache.invalidateAll();
+ appCache.invalidateAll();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/4c8727c1/stack/core/src/main/resources/usergrid-core-context.xml
----------------------------------------------------------------------
diff --git a/stack/core/src/main/resources/usergrid-core-context.xml b/stack/core/src/main/resources/usergrid-core-context.xml
index c8ce0d8..cd40d6d 100644
--- a/stack/core/src/main/resources/usergrid-core-context.xml
+++ b/stack/core/src/main/resources/usergrid-core-context.xml
@@ -54,7 +54,7 @@
<constructor-arg value="${cassandra.url}" />
<!-- set the pool size if it's available. If not go with 50 -->
<property name="maxActive" value="${cassandra.connections:50}"/>
- <!--<property name="clockResolution" ref="microsecondsTimeResolution" />-->
+ <!--<property orgAppName="clockResolution" ref="microsecondsTimeResolution" />-->
<property name="opTimer" ref="taggedOpTimer"/>
<property name="loadBalancingPolicy" ref="loadBalancingPolicy"/>
</bean>
@@ -70,7 +70,7 @@
<bean id="loadBalancingPolicy" class="me.prettyprint.cassandra.connection.DynamicLoadBalancingPolicy"/>
<!-- locking for a single node -->
-<!-- <bean name="lockManager"
+<!-- <bean orgAppName="lockManager"
class="org.apache.usergrid.locking.singlenode.SingleNodeLockManagerImpl" />-->
<!-- hector based locks -->
@@ -86,10 +86,10 @@
<!-- zookeeper locks -->
<!--
- <bean name="lockManager" class="org.apache.usergrid.locking.zookeeper.ZooKeeperLockManagerImpl" >
- <property name="hostPort" value="${zookeeper.url}"/>
- <property name="sessionTimeout" value="2000"/>
- <property name="maxAttempts" value="10"/>
+ <bean orgAppName="lockManager" class="org.apache.usergrid.locking.zookeeper.ZooKeeperLockManagerImpl" >
+ <property orgAppName="hostPort" value="${zookeeper.url}"/>
+ <property orgAppName="sessionTimeout" value="2000"/>
+ <property orgAppName="maxAttempts" value="10"/>
</bean> -->
@@ -196,7 +196,7 @@
</bean>
<bean id="jobFactory" class="org.apache.usergrid.batch.UsergridJobFactory" />
-
+
<context:component-scan base-package="org.apache.usergrid.batch.job" />
<context:annotation-config />
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/4c8727c1/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndexFactory.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndexFactory.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndexFactory.java
index 78a5137..10752d1 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndexFactory.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndexFactory.java
@@ -25,6 +25,8 @@ import com.google.inject.assistedinject.Assisted;
public interface EntityIndexFactory {
- public EntityIndex createEntityIndex(
+ public EntityIndex createEntityIndex(
@Assisted ApplicationScope appScope);
+
+ void invalidate();
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/4c8727c1/stack/services/src/main/resources/usergrid-services-context.xml
----------------------------------------------------------------------
diff --git a/stack/services/src/main/resources/usergrid-services-context.xml b/stack/services/src/main/resources/usergrid-services-context.xml
index 666051d..8674b71 100644
--- a/stack/services/src/main/resources/usergrid-services-context.xml
+++ b/stack/services/src/main/resources/usergrid-services-context.xml
@@ -103,10 +103,10 @@
<!--<bean id="importQueueListener" class="org.apache.usergrid.services.queues.ImportQueueListener"-->
<!--scope="singleton">-->
- <!--<constructor-arg name="emf" ref="entityManagerFactory" />-->
- <!--<constructor-arg name="metricsService" ref="metricsFactory" />-->
- <!--<constructor-arg name="smf" ref="serviceManagerFactory" />-->
- <!--<constructor-arg name="props" ref="properties" />-->
+ <!--<constructor-arg orgAppName="emf" ref="entityManagerFactory" />-->
+ <!--<constructor-arg orgAppName="metricsService" ref="metricsFactory" />-->
+ <!--<constructor-arg orgAppName="smf" ref="serviceManagerFactory" />-->
+ <!--<constructor-arg orgAppName="props" ref="properties" />-->
<!--</bean>-->