You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sf...@apache.org on 2015/02/16 23:01:47 UTC

[40/50] incubator-usergrid git commit: Added a cache proxy at the collection manager tier.

Added a cache proxy at the collection manager tier.


Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/7abf3b72
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/7abf3b72
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/7abf3b72

Branch: refs/heads/USERGRID-365
Commit: 7abf3b7253b9ba1165c448d8a18f7b275ea92cae
Parents: 4d5e5e6
Author: Todd Nine <tn...@apigee.com>
Authored: Mon Feb 16 12:33:28 2015 -0800
Committer: Todd Nine <tn...@apigee.com>
Committed: Mon Feb 16 12:33:28 2015 -0800

----------------------------------------------------------------------
 .../corepersistence/CpEntityManager.java        |  38 +----
 .../corepersistence/CpManagerCache.java         |  17 +-
 .../corepersistence/CpRelationManager.java      |   8 +-
 .../cache/CachedEntityCollectionManager.java    | 136 ++++++++++++++++
 .../collection/cache/EntityCacheFig.java        |  44 +++++
 .../collection/guice/CollectionModule.java      |  14 +-
 .../EntityCollectionManagerFactoryImpl.java     | 159 +++++++++++++++++++
 .../impl/EntityCollectionManagerImpl.java       |  19 +--
 .../EntityCollectionManagerFactoryTest.java     |   2 +-
 9 files changed, 369 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/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 0a22845..e117a73 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
@@ -193,8 +193,8 @@ public class CpEntityManager implements EntityManager {
 
     private boolean skipAggregateCounters;
 
-    /** Short-term cache to keep us from reloading same Entity during single request. */
-    private LoadingCache<EntityScope, org.apache.usergrid.persistence.model.entity.Entity> entityCache;
+//    /** Short-term cache to keep us from reloading same Entity during single request. */
+//    private LoadingCache<EntityScope, org.apache.usergrid.persistence.model.entity.Entity> entityCache;
 
 
     public CpEntityManager() {}
@@ -218,24 +218,7 @@ public class CpEntityManager implements EntityManager {
         // set to false for now
         this.skipAggregateCounters = false;
 
-        int entityCacheSize = Integer.parseInt( cass.getProperties()
-                .getProperty( "usergrid.entity_cache_size", "100" ) );
 
-        int entityCacheTimeout = Integer.parseInt( cass.getProperties()
-                .getProperty( "usergrid.entity_cache_timeout_ms", "500" ) );
-
-        this.entityCache = CacheBuilder.newBuilder()
-            .maximumSize(entityCacheSize)
-            .expireAfterWrite(entityCacheTimeout, TimeUnit.MILLISECONDS)
-            .build( new CacheLoader<EntityScope, org.apache.usergrid.persistence.model.entity.Entity>() {
-
-                public org.apache.usergrid.persistence.model.entity.Entity load( EntityScope es) {
-                        return managerCache.getEntityCollectionManager(es.scope)
-                            .load(es.entityId).toBlocking()
-                            .lastOrDefault(null);
-                    }
-                }
-            );
     }
 
 
@@ -267,17 +250,11 @@ public class CpEntityManager implements EntityManager {
      * @return Entity or null if not found
      */
     org.apache.usergrid.persistence.model.entity.Entity load( EntityScope es ) {
-        try {
-            return entityCache.get( es );
-        }
-        catch ( InvalidCacheLoadException icle ) {
-            // fine, entity not found
-            return null;
-        }
-        catch ( ExecutionException exex ) {
-            // uh-oh, more serious problem
-            throw new RuntimeException( "Error loading entity", exex );
-        }
+
+            return managerCache.getEntityCollectionManager(es.scope)
+                                       .load(es.entityId).toBlocking()
+                                       .lastOrDefault(null);
+
     }
 
 
@@ -2508,7 +2485,6 @@ public class CpEntityManager implements EntityManager {
                     cpEntity.getId().getType(), cpEntity.getId().getUuid(), cpEntity.getVersion()
             } );
 
-            entityCache.put( new EntityScope( collectionScope, cpEntity.getId() ), cpEntity );
         }
         catch ( WriteUniqueVerifyException wuve ) {
             handleWriteUniqueVerifyException( entity, wuve );

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java
index e29e5c2..ca7a004 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpManagerCache.java
@@ -45,14 +45,6 @@ public class CpManagerCache implements ManagerCache {
 
     // TODO: consider making these cache sizes and timeouts configurable
 
-    private LoadingCache<CollectionScope, EntityCollectionManager> ecmCache =
-            CacheBuilder.newBuilder().maximumSize( 1000 )
-                        .build( new CacheLoader<CollectionScope, EntityCollectionManager>() {
-                                    public EntityCollectionManager load( CollectionScope scope ) {
-                                        return ecmf.createCollectionManager( scope );
-                                    }
-                                } );
-
     private LoadingCache<ApplicationScope, EntityIndex> eiCache =
             CacheBuilder.newBuilder().maximumSize( 1000 ).build( new CacheLoader<ApplicationScope, EntityIndex>() {
                                                                      public EntityIndex load( ApplicationScope scope ) {
@@ -89,12 +81,8 @@ public class CpManagerCache implements ManagerCache {
 
     @Override
     public EntityCollectionManager getEntityCollectionManager( CollectionScope scope ) {
-        try {
-            return ecmCache.get( scope );
-        }
-        catch ( ExecutionException ex ) {
-            throw new RuntimeException( "Error getting manager", ex );
-        }
+        //cache is now in the colletion manager level
+        return ecmf.createCollectionManager( scope );
     }
 
 
@@ -133,7 +121,6 @@ public class CpManagerCache implements ManagerCache {
 
     @Override
     public void invalidate() {
-        ecmCache.invalidateAll();
         eiCache.invalidateAll();
         gmCache.invalidateAll();
         mmCache.invalidateAll();

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
index b7a82fd..7be6dea 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
@@ -235,12 +235,12 @@ public class CpRelationManager implements RelationManager {
 
         Id entityId = new SimpleId( headEntity.getUuid(), headEntity.getType() );
 
-        if(headEntity instanceof Entity){
-            cpHeadEntity = entityToCpEntity( (Entity)headEntity, headEntity.getUuid() );
-        }else {
+//        if(headEntity instanceof Entity){
+//            cpHeadEntity = entityToCpEntity( (Entity)headEntity, headEntity.getUuid() );
+//        }else {
             this.cpHeadEntity =
                 ( ( CpEntityManager ) em ).load( new CpEntityManager.EntityScope( headEntityScope, entityId ) );
-        }
+//        }
 
         // commented out because it is possible that CP entity has not been created yet
         Assert.notNull( cpHeadEntity, "cpHeadEntity cannot be null" );

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/cache/CachedEntityCollectionManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/cache/CachedEntityCollectionManager.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/cache/CachedEntityCollectionManager.java
new file mode 100644
index 0000000..5430759
--- /dev/null
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/cache/CachedEntityCollectionManager.java
@@ -0,0 +1,136 @@
+/*
+ * 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.persistence.collection.cache;
+
+
+import java.util.Collection;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.usergrid.persistence.collection.EntityCollectionManager;
+import org.apache.usergrid.persistence.collection.EntitySet;
+import org.apache.usergrid.persistence.collection.VersionSet;
+import org.apache.usergrid.persistence.core.util.Health;
+import org.apache.usergrid.persistence.model.entity.Entity;
+import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.field.Field;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import rx.Observable;
+import rx.functions.Action1;
+
+
+@Singleton
+public class CachedEntityCollectionManager implements EntityCollectionManager {
+
+    /**
+     * The collection manager we perform real i/o from
+     */
+    private EntityCollectionManager targetEntityCollectionManager;
+
+
+    /** Short-term cache to keep us from reloading same Entity during single request. */
+    private Cache<Id, Entity> entityCache;
+
+    private Action1<Entity> cacheAdd = new Action1<Entity>() {
+        @Override
+        public void call( final Entity entity ) {
+            entityCache.put( entity.getId(), entity );
+        }
+    };
+
+
+    @Inject
+    public CachedEntityCollectionManager( final EntityCacheFig entityCacheFig,
+                                          final EntityCollectionManager targetEntityCollectionManager ) {
+        this.targetEntityCollectionManager = targetEntityCollectionManager;
+
+
+        entityCache = CacheBuilder.newBuilder().maximumSize( entityCacheFig.getCacheSize() )
+                                  .expireAfterWrite( entityCacheFig.getCacheTimeout(), TimeUnit.SECONDS )
+                                  .build();
+    }
+
+
+    @Override
+    public Observable<Entity> write( final Entity entity ) {
+        return targetEntityCollectionManager.write( entity ).doOnNext( cacheAdd );
+    }
+
+
+    @Override
+    public Observable<Id> delete( final Id entityId ) {
+        return targetEntityCollectionManager.delete( entityId ).doOnNext( new Action1<Id>() {
+            @Override
+            public void call( final Id id ) {
+                entityCache.invalidate( id );
+            }
+        } );
+    }
+
+
+    @Override
+    public Observable<Entity> load( final Id entityId ) {
+        final Entity entity = entityCache.getIfPresent( entityId );
+
+        if ( entity != null ) {
+            return Observable.just( entity );
+        }
+
+        return Observable.empty();
+
+    }
+
+
+    @Override
+    public Observable<VersionSet> getLatestVersion( final Collection<Id> entityId ) {
+        return targetEntityCollectionManager.getLatestVersion( entityId );
+    }
+
+
+    @Override
+    public Observable<Id> getIdField( final Field field ) {
+        return targetEntityCollectionManager.getIdField( field );
+    }
+
+
+    @Override
+    public Observable<EntitySet> load( final Collection<Id> entityIds ) {
+        return targetEntityCollectionManager.load( entityIds );
+    }
+
+
+    @Override
+    public Observable<Entity> update( final Entity entity ) {
+        return targetEntityCollectionManager.update( entity ).doOnNext( cacheAdd );
+    }
+
+
+    @Override
+    public Health getHealth() {
+        return targetEntityCollectionManager.getHealth();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/cache/EntityCacheFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/cache/EntityCacheFig.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/cache/EntityCacheFig.java
new file mode 100644
index 0000000..f62e713
--- /dev/null
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/cache/EntityCacheFig.java
@@ -0,0 +1,44 @@
+/*
+ * 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.persistence.collection.cache;
+
+
+import org.safehaus.guicyfig.Default;
+import org.safehaus.guicyfig.GuicyFig;
+import org.safehaus.guicyfig.Key;
+
+
+/**
+ * The config for the entity cache
+ */
+public interface EntityCacheFig extends GuicyFig {
+
+
+    @Key( "usergrid.entity_cache_size" )
+    @Default( "10000" )
+    int getCacheSize();
+
+    @Key( "usergrid.entity_cache_timeout_ms" )
+    @Default( "500" )
+    int getCacheTimeout();
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/guice/CollectionModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/guice/CollectionModule.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/guice/CollectionModule.java
index 1c3e258..7cd383a 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/guice/CollectionModule.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/guice/CollectionModule.java
@@ -27,8 +27,10 @@ import org.apache.usergrid.persistence.collection.EntityCollectionManagerSync;
 import org.apache.usergrid.persistence.collection.EntityDeletedFactory;
 import org.apache.usergrid.persistence.collection.EntityVersionCleanupFactory;
 import org.apache.usergrid.persistence.collection.EntityVersionCreatedFactory;
+import org.apache.usergrid.persistence.collection.cache.EntityCacheFig;
 import org.apache.usergrid.persistence.collection.event.EntityDeleted;
 import org.apache.usergrid.persistence.collection.event.EntityVersionDeleted;
+import org.apache.usergrid.persistence.collection.impl.EntityCollectionManagerFactoryImpl;
 import org.apache.usergrid.persistence.collection.impl.EntityCollectionManagerImpl;
 import org.apache.usergrid.persistence.collection.impl.EntityCollectionManagerSyncImpl;
 import org.apache.usergrid.persistence.collection.mvcc.MvccLogEntrySerializationStrategy;
@@ -51,6 +53,7 @@ import com.google.inject.Singleton;
 import com.google.inject.assistedinject.FactoryModuleBuilder;
 import com.google.inject.multibindings.Multibinder;
 import org.apache.usergrid.persistence.collection.event.EntityVersionCreated;
+import org.apache.usergrid.persistence.model.entity.Entity;
 
 
 /**
@@ -80,11 +83,10 @@ public class CollectionModule extends AbstractModule {
         Multibinder.newSetBinder( binder(), EntityVersionCreated.class );
         Multibinder.newSetBinder( binder(), EntityDeleted.class );
 
-        // create a guice factor for getting our collection manager
-        install( new FactoryModuleBuilder()
-            .implement( EntityCollectionManager.class, EntityCollectionManagerImpl.class )
-            .implement( EntityCollectionManagerSync.class, EntityCollectionManagerSyncImpl.class )
-            .build( EntityCollectionManagerFactory.class ) );
+
+        //bind this to our factory
+        bind( EntityCollectionManagerFactory.class).to( EntityCollectionManagerFactoryImpl.class );
+        install( new GuicyFigModule( EntityCacheFig.class ) );
 
         bind( UniqueValueSerializationStrategy.class ).to( UniqueValueSerializationStrategyImpl.class );
         bind( ChangeLogGenerator.class).to( ChangeLogGeneratorImpl.class);
@@ -116,7 +118,7 @@ public class CollectionModule extends AbstractModule {
     @Provides
     @CollectionTaskExecutor
     public TaskExecutor collectionTaskExecutor(final SerializationFig serializationFig){
-        return new NamedTaskExecutorImpl( "collectiontasks", 
+        return new NamedTaskExecutorImpl( "collectiontasks",
                 serializationFig.getTaskPoolThreadSize(), serializationFig.getTaskPoolQueueSize() );
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerFactoryImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerFactoryImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerFactoryImpl.java
new file mode 100644
index 0000000..0b9c643
--- /dev/null
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerFactoryImpl.java
@@ -0,0 +1,159 @@
+/*
+ * 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.persistence.collection.impl;
+
+
+import java.util.concurrent.ExecutionException;
+
+import org.apache.usergrid.persistence.collection.CollectionScope;
+import org.apache.usergrid.persistence.collection.EntityCollectionManager;
+import org.apache.usergrid.persistence.collection.EntityCollectionManagerFactory;
+import org.apache.usergrid.persistence.collection.EntityCollectionManagerSync;
+import org.apache.usergrid.persistence.collection.EntityDeletedFactory;
+import org.apache.usergrid.persistence.collection.EntityVersionCleanupFactory;
+import org.apache.usergrid.persistence.collection.EntityVersionCreatedFactory;
+import org.apache.usergrid.persistence.collection.cache.CachedEntityCollectionManager;
+import org.apache.usergrid.persistence.collection.cache.EntityCacheFig;
+import org.apache.usergrid.persistence.collection.guice.CollectionTaskExecutor;
+import org.apache.usergrid.persistence.collection.guice.Write;
+import org.apache.usergrid.persistence.collection.guice.WriteUpdate;
+import org.apache.usergrid.persistence.collection.mvcc.MvccEntitySerializationStrategy;
+import org.apache.usergrid.persistence.collection.mvcc.MvccLogEntrySerializationStrategy;
+import org.apache.usergrid.persistence.collection.mvcc.stage.delete.MarkCommit;
+import org.apache.usergrid.persistence.collection.mvcc.stage.delete.MarkStart;
+import org.apache.usergrid.persistence.collection.mvcc.stage.write.RollbackAction;
+import org.apache.usergrid.persistence.collection.mvcc.stage.write.WriteCommit;
+import org.apache.usergrid.persistence.collection.mvcc.stage.write.WriteOptimisticVerify;
+import org.apache.usergrid.persistence.collection.mvcc.stage.write.WriteStart;
+import org.apache.usergrid.persistence.collection.mvcc.stage.write.WriteUniqueVerify;
+import org.apache.usergrid.persistence.collection.serialization.SerializationFig;
+import org.apache.usergrid.persistence.collection.serialization.UniqueValueSerializationStrategy;
+import org.apache.usergrid.persistence.core.guice.ProxyImpl;
+import org.apache.usergrid.persistence.core.task.TaskExecutor;
+
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
+
+
+/**
+ * returns Entity Collection Managers built to manage caching
+ */
+@Singleton
+public class EntityCollectionManagerFactoryImpl implements EntityCollectionManagerFactory {
+
+
+    private final WriteStart writeStart;
+    private final WriteStart writeUpdate;
+    private final WriteUniqueVerify writeVerifyUnique;
+    private final WriteOptimisticVerify writeOptimisticVerify;
+    private final WriteCommit writeCommit;
+    private final RollbackAction rollback;
+    private final MarkStart markStart;
+    private final MarkCommit markCommit;
+    private final MvccEntitySerializationStrategy entitySerializationStrategy;
+    private final UniqueValueSerializationStrategy uniqueValueSerializationStrategy;
+    private final MvccLogEntrySerializationStrategy mvccLogEntrySerializationStrategy;
+    private final Keyspace keyspace;
+    private final EntityVersionCleanupFactory entityVersionCleanupFactory;
+    private final EntityVersionCreatedFactory entityVersionCreatedFactory;
+    private final EntityDeletedFactory entityDeletedFactory;
+    private final TaskExecutor taskExecutor;
+    private final EntityCacheFig entityCacheFig;
+
+    private LoadingCache<CollectionScope, EntityCollectionManager> ecmCache =
+        CacheBuilder.newBuilder().maximumSize( 1000 )
+                    .build( new CacheLoader<CollectionScope, EntityCollectionManager>() {
+                        public EntityCollectionManager load( CollectionScope scope ) {
+
+                                  //create the target EM that will perform logic
+                            final EntityCollectionManager target = new EntityCollectionManagerImpl( writeStart, writeUpdate, writeVerifyUnique,
+                                writeOptimisticVerify, writeCommit, rollback, markStart, markCommit,
+                                entitySerializationStrategy, uniqueValueSerializationStrategy,
+                                mvccLogEntrySerializationStrategy, keyspace, entityVersionCleanupFactory,
+                                entityVersionCreatedFactory, entityDeletedFactory, taskExecutor, scope );
+
+
+                            final EntityCollectionManager proxy = new CachedEntityCollectionManager(entityCacheFig, target  );
+
+                            return proxy;
+                        }
+                    } );
+
+
+    @Inject
+    public EntityCollectionManagerFactoryImpl( @Write final WriteStart writeStart,
+                                               @WriteUpdate final WriteStart writeUpdate,
+                                               final WriteUniqueVerify writeVerifyUnique,
+                                               final WriteOptimisticVerify writeOptimisticVerify,
+                                               final WriteCommit writeCommit, final RollbackAction rollback,
+                                               final MarkStart markStart, final MarkCommit markCommit, @ProxyImpl
+                                               final MvccEntitySerializationStrategy entitySerializationStrategy,
+                                               final UniqueValueSerializationStrategy uniqueValueSerializationStrategy,
+                                               final MvccLogEntrySerializationStrategy
+                                                   mvccLogEntrySerializationStrategy,
+                                               final Keyspace keyspace,
+                                               final EntityVersionCleanupFactory entityVersionCleanupFactory,
+                                               final EntityVersionCreatedFactory entityVersionCreatedFactory,
+                                               final EntityDeletedFactory entityDeletedFactory,
+                                               @CollectionTaskExecutor final TaskExecutor taskExecutor,
+                                              final EntityCacheFig entityCacheFig) {
+
+        this.writeStart = writeStart;
+        this.writeUpdate = writeUpdate;
+        this.writeVerifyUnique = writeVerifyUnique;
+        this.writeOptimisticVerify = writeOptimisticVerify;
+        this.writeCommit = writeCommit;
+        this.rollback = rollback;
+        this.markStart = markStart;
+        this.markCommit = markCommit;
+        this.entitySerializationStrategy = entitySerializationStrategy;
+        this.uniqueValueSerializationStrategy = uniqueValueSerializationStrategy;
+        this.mvccLogEntrySerializationStrategy = mvccLogEntrySerializationStrategy;
+        this.keyspace = keyspace;
+        this.entityVersionCleanupFactory = entityVersionCleanupFactory;
+        this.entityVersionCreatedFactory = entityVersionCreatedFactory;
+        this.entityDeletedFactory = entityDeletedFactory;
+        this.taskExecutor = taskExecutor;
+        this.entityCacheFig = entityCacheFig;
+    }
+
+
+    @Override
+    public EntityCollectionManager createCollectionManager( CollectionScope collectionScope ) {
+        Preconditions.checkNotNull( collectionScope );
+        try {
+            return ecmCache.get( collectionScope );
+        }
+        catch ( ExecutionException ee ) {
+            throw new RuntimeException( ee );
+        }
+    }
+
+
+    @Override
+    public EntityCollectionManagerSync createCollectionManagerSync( CollectionScope collectionScope ) {
+        return new EntityCollectionManagerSyncImpl( this, collectionScope );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
index a89924a..8c754c1 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
@@ -113,24 +113,22 @@ public class EntityCollectionManagerImpl implements EntityCollectionManager {
     private final TaskExecutor taskExecutor;
 
     private final Keyspace keyspace;
-    private SerializationFig config;
 
 
     @Inject
-    public EntityCollectionManagerImpl( 
-        @Write final WriteStart                    writeStart, 
+    public EntityCollectionManagerImpl(
+        @Write final WriteStart                    writeStart,
         @WriteUpdate final WriteStart              writeUpdate,
         final WriteUniqueVerify                    writeVerifyUnique,
         final WriteOptimisticVerify                writeOptimisticVerify,
-        final WriteCommit                          writeCommit, 
+        final WriteCommit                          writeCommit,
         final RollbackAction                       rollback,
-        final MarkStart                            markStart, 
+        final MarkStart                            markStart,
         final MarkCommit                           markCommit,
         @ProxyImpl final MvccEntitySerializationStrategy entitySerializationStrategy,
         final UniqueValueSerializationStrategy     uniqueValueSerializationStrategy,
         final MvccLogEntrySerializationStrategy    mvccLogEntrySerializationStrategy,
-        final Keyspace                             keyspace, 
-        final SerializationFig                     config,
+        final Keyspace                             keyspace,
         final EntityVersionCleanupFactory          entityVersionCleanupFactory,
         final EntityVersionCreatedFactory          entityVersionCreatedFactory,
         final EntityDeletedFactory                 entityDeletedFactory,
@@ -154,7 +152,6 @@ public class EntityCollectionManagerImpl implements EntityCollectionManager {
         this.markCommit = markCommit;
 
         this.keyspace = keyspace;
-        this.config = config;
 
         this.entityVersionCleanupFactory = entityVersionCleanupFactory;
         this.entityVersionCreatedFactory = entityVersionCreatedFactory;
@@ -182,9 +179,9 @@ public class EntityCollectionManagerImpl implements EntityCollectionManager {
 
         Observable<CollectionIoEvent<MvccEntity>> observable = stageRunner( writeData, writeStart );
 
-        // execute all validation stages concurrently.  Needs refactored when this is done.  
+        // execute all validation stages concurrently.  Needs refactored when this is done.
         // https://github.com/Netflix/RxJava/issues/627
-        // observable = Concurrent.concurrent( observable, Schedulers.io(), new WaitZip(), 
+        // observable = Concurrent.concurrent( observable, Schedulers.io(), new WaitZip(),
         //                  writeVerifyUnique, writeOptimisticVerify );
 
         return observable.map(writeCommit).doOnNext(new Action1<Entity>() {
@@ -402,4 +399,4 @@ public class EntityCollectionManagerImpl implements EntityCollectionManager {
 
         return Health.RED;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7abf3b72/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerFactoryTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerFactoryTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerFactoryTest.java
index 0d44e98..fe984a2 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerFactoryTest.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerFactoryTest.java
@@ -47,7 +47,7 @@ public class EntityCollectionManagerFactoryTest {
     }
 
 
-    @Test(expected = ProvisionException.class)
+    @Test(expected = NullPointerException.class)
     public void nullInput() {
         entityCollectionManagerFactory.createCollectionManager( null );
     }