You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2015/07/09 10:48:01 UTC

[1/3] zest-qi4j git commit: Giving some love to the InvocationCache library, which was simply in a very bad shape.

Repository: zest-qi4j
Updated Branches:
  refs/heads/develop 8f87df34c -> 4076eae35


Giving some love to the InvocationCache library, which was simply in a very bad shape.


Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/c24b54ec
Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/c24b54ec
Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/c24b54ec

Branch: refs/heads/develop
Commit: c24b54ecca37845c0665bb1575bdd3d09b97c3e2
Parents: 8f87df3
Author: Niclas Hedhman <he...@betfair.com>
Authored: Thu Jul 9 11:16:54 2015 +0300
Committer: Niclas Hedhman <he...@betfair.com>
Committed: Thu Jul 9 11:16:54 2015 +0300

----------------------------------------------------------------------
 .../src/docs/invocation-cache.txt               | 69 +++++++++++++++++++-
 .../CacheInvocationResultSideEffect.java        | 62 ------------------
 .../InvalidateCacheOnSettersSideEffect.java     | 53 ---------------
 .../invocationcache/InvocationCache.java        |  3 +
 .../InvocationCacheAbstractComposite.java       | 32 ---------
 .../invocationcache/InvocationCacheMixin.java   | 60 -----------------
 .../ReturnCachedValueConcern.java               | 26 ++++----
 .../ReturnCachedValueOnExceptionConcern.java    | 33 +++++-----
 .../SimpleInvocationCacheMixin.java             | 69 ++++++++++++++++++++
 .../invocationcache/DocumentationSupport.java   | 51 +++++++++++++++
 10 files changed, 215 insertions(+), 243 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/docs/invocation-cache.txt
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/docs/invocation-cache.txt b/libraries/invocation-cache/src/docs/invocation-cache.txt
index da5e60f..40600b7 100644
--- a/libraries/invocation-cache/src/docs/invocation-cache.txt
+++ b/libraries/invocation-cache/src/docs/invocation-cache.txt
@@ -25,9 +25,72 @@
 source=libraries/invocation-cache/dev-status.xml
 --------------
 
-The Invocation Cache Library provides constructs to easily cache composite methods invocations.
-It has nothing to do with the <<core-spi-cache>>.
+The Invocation Cache Library provides constructs to easily cache the return value of
+method invocations on composites.
 
-NOTE: This Library has no documentation yet. Learn how to contribute in <<community-docs>>.
+NOTE: It has nothing to do with the <<core-spi-cache>>.
 
 include::../../build/docs/buildinfo/artifact.txt[]
+
+
+By applying one of the <<def-concern,Concerns>> it is possible to cache the return values of method
+calls. The concern will in turn delegate to the +InvocationCache+ that is expected to be a
+<<def-private-mixin>> in the same composite.
+
+== +@Cached+ ==
+This annotation is used to mark the methods that should be considered for caching. Only if a
+caching concern has been defined and that an +InvocationCache+ implementation mixin has been provided
+will the caching actually take place.
+
+== +ReturnCachedValueConcern+ ==
+This generic mixin implementation will first look in the cache and see if the value is there, if so the value
+is unconditionally returned to the caller.
+
+This concern skip its function if there is no +InvocationCache+ mixin declared on the composite or if the method
+has a +void+ return type.
+
+== +ReturnCachedValueOnExceptionConcern+ ==
+This generic mixin implementation will first call the method, and if it fails with an Exception, it will try to
+return a value from the cache. If no value is present in the cache (i.e. null is returned from the cache) then
+the exception will be rethrown.
+
+This concern skip its function if there is no +InvocationCache+ mixin declared on the composite or if the method
+has a +void+ return type.
+
+== Example ==
+
+Let's say that we have some service that is very expensive to call.
+
+[snippet,java]
+----
+source=libraries/invocationcache/src/test/java/org/qi4j/library/invocationcache/DocumentationSupport.java
+tag=composite
+----
+
+And we know that the argument combinations into this method are relatively few, we can simply declare the
++SimpleInvocationCache+ mixin implementation to store the permutations and return them if already been
+provided.
+
+[snippet,java]
+----
+source=libraries/invocationcache/src/test/java/org/qi4j/library/invocationcache/DocumentationSupport.java
+tag=assembly
+----
+
+It is important to realize that the +SimpleInvocationCache+ implementation never drops the cached values,
+and it is not possible to instruct it to do so. So, in most cases it is required to implement the +InvocationCache+
+interface yourself, and choose a caching strategy that works for you.
+
+== Custom +InvocationCache+ implementation ==
+The interface to implement is very straight forward. It is important to realize that the implementation is a
+<<def-private-mixin>> of the composite where the caching is applied, and not a separate service. So, if
+the implementation is expecting to be part of an entity, it is possible to have
+
+[source,java]
+----
+@This
+private Identity myIdentity;
+----
+
+to get hold of the current entity's +Identity+. This approach makes the caching a lot simpler than if a separate
+service would have been used instead, but still possible to delegate to such.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/CacheInvocationResultSideEffect.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/CacheInvocationResultSideEffect.java b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/CacheInvocationResultSideEffect.java
deleted file mode 100644
index fb3e73b..0000000
--- a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/CacheInvocationResultSideEffect.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2007 Rickard Öberg.
- *
- * Licensed  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.qi4j.library.invocationcache;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import org.qi4j.api.common.AppliesTo;
-import org.qi4j.api.injection.scope.Invocation;
-import org.qi4j.api.injection.scope.This;
-import org.qi4j.api.sideeffect.GenericSideEffect;
-
-/**
- * Cache result of @Cached method calls.
- */
-@AppliesTo( Cached.class )
-public class CacheInvocationResultSideEffect
-    extends GenericSideEffect
-{
-    @This
-    private InvocationCache cache;
-    @Invocation
-    private Method method;
-
-    @Override
-    public Object invoke( Object proxy, Method method, Object[] args )
-        throws Throwable
-    {
-        // Get value
-        // if an exception is thrown, don't do anything
-        Object res = result.invoke( proxy, method, args );
-        if( res == null )
-        {
-            res = Void.TYPE;
-        }
-        String cacheName = method.getName();
-        if( args != null )
-        {
-            cacheName += Arrays.asList( args );
-        }
-        Object oldResult = cache.cachedValue( cacheName );
-        if( oldResult == null || !oldResult.equals( result ) )
-        {
-            cache.setCachedValue( cacheName, result );
-        }
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvalidateCacheOnSettersSideEffect.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvalidateCacheOnSettersSideEffect.java b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvalidateCacheOnSettersSideEffect.java
deleted file mode 100644
index f819a76..0000000
--- a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvalidateCacheOnSettersSideEffect.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2007 Rickard Öberg.
- *
- * Licensed  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.qi4j.library.invocationcache;
-
-import java.lang.reflect.Method;
-import org.qi4j.api.common.AppliesTo;
-import org.qi4j.api.common.AppliesToFilter;
-import org.qi4j.api.injection.scope.This;
-import org.qi4j.api.sideeffect.GenericSideEffect;
-
-/**
- * Invalidate cache on setters.
- */
-@AppliesTo( InvalidateCacheOnSettersSideEffect.AppliesTo.class )
-public class InvalidateCacheOnSettersSideEffect
-    extends GenericSideEffect
-{
-    public static class AppliesTo
-        implements AppliesToFilter
-    {
-        @Override
-        public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> modifierClass )
-        {
-            return !( method.getDeclaringClass().equals( InvocationCache.class )
-                      || method.getDeclaringClass().equals( InvocationCacheMixin.class ) );
-
-        }
-    }
-
-    @This
-    private InvocationCache cache;
-
-    @Override
-    protected void invoke( Method method, Object[] args )
-    {
-        cache.clearCachedValues();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCache.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCache.java b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCache.java
index 7d83355..4ab8e9c 100644
--- a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCache.java
+++ b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCache.java
@@ -17,9 +17,12 @@
  */
 package org.qi4j.library.invocationcache;
 
+import org.qi4j.api.mixin.Mixins;
+
 /**
  * Invocation Cache.
  */
+@Mixins( SimpleInvocationCacheMixin.class )
 public interface InvocationCache
 {
     Object setCachedValue( String name, Object aResult );

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCacheAbstractComposite.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCacheAbstractComposite.java b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCacheAbstractComposite.java
deleted file mode 100644
index 183c490..0000000
--- a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCacheAbstractComposite.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2007 Rickard Öberg.
- *
- * Licensed  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.qi4j.library.invocationcache;
-
-import org.qi4j.api.concern.Concerns;
-import org.qi4j.api.mixin.Mixins;
-import org.qi4j.api.sideeffect.SideEffects;
-
-/**
- * JAVADOC
- */
-@Mixins( InvocationCacheMixin.class )
-@Concerns( ReturnCachedValueOnExceptionConcern.class )
-@SideEffects( { CacheInvocationResultSideEffect.class, InvalidateCacheOnSettersSideEffect.class } )
-public interface InvocationCacheAbstractComposite
-{
-}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCacheMixin.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCacheMixin.java b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCacheMixin.java
deleted file mode 100644
index b45a4a3..0000000
--- a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/InvocationCacheMixin.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2007 Rickard Öberg.
- *
- * Licensed  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.qi4j.library.invocationcache;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Default implementation of InvocationCache.
- */
-public class InvocationCacheMixin
-    implements InvocationCache
-{
-    private final Map<String, Object> cachedValues = new ConcurrentHashMap<>();
-
-    @Override
-    public Object setCachedValue( String name, Object aResult )
-    {
-        return cachedValues.put( name, aResult );
-    }
-
-    @Override
-    public Object cachedValue( String name )
-    {
-        return cachedValues.get( name );
-    }
-
-    @Override
-    public Object removeCachedValue( String name )
-    {
-        return cachedValues.remove( name );
-    }
-
-    @Override
-    public void clearCachedValues()
-    {
-        cachedValues.clear();
-    }
-
-    @Override
-    public int currentCacheSize()
-    {
-        return cachedValues.size();
-    }
-}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueConcern.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueConcern.java b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueConcern.java
index 8c0d2d2..9ad0d3f 100644
--- a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueConcern.java
+++ b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueConcern.java
@@ -21,6 +21,7 @@ import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import org.qi4j.api.common.AppliesTo;
+import org.qi4j.api.common.Optional;
 import org.qi4j.api.concern.ConcernOf;
 import org.qi4j.api.injection.scope.Invocation;
 import org.qi4j.api.injection.scope.This;
@@ -33,34 +34,29 @@ public class ReturnCachedValueConcern
     extends ConcernOf<InvocationHandler>
     implements InvocationHandler
 {
-    @This
+    @This @Optional
     private InvocationCache cache;
-    @Invocation
-    private Method method;
 
     @Override
     public Object invoke( Object proxy, Method method, Object[] args )
         throws Throwable
     {
-        // Try cache
-        String cacheName = method.getName();
-        if( args != null )
+        boolean voidReturnType = method.getReturnType().equals( Void.TYPE );
+        if( cache != null || voidReturnType )
         {
-            cacheName += Arrays.asList( args );
-        }
-        Object result = cache.cachedValue( cacheName );
-        if( result != null )
-        {
-            if( result == Void.TYPE )
+            // Try cache
+            String cacheName = method.getName();
+            if( args != null )
             {
-                return null;
+                cacheName += Arrays.asList( args );
             }
-            else
+            Object result = cache.cachedValue( cacheName );
+            if( result != null )
             {
                 return result;
             }
         }
-        // No cached value found - call method
+        // No cached value found or no InvocationCache defined - call method
         return next.invoke( proxy, method, args );
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueOnExceptionConcern.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueOnExceptionConcern.java b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueOnExceptionConcern.java
index 400baf5..1287b39 100644
--- a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueOnExceptionConcern.java
+++ b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/ReturnCachedValueOnExceptionConcern.java
@@ -42,32 +42,29 @@ public class ReturnCachedValueOnExceptionConcern
     public Object invoke( Object proxy, Method method, Object[] args )
         throws Throwable
     {
-        try
+        boolean voidReturnType = method.getReturnType().equals( Void.TYPE );
+        if( cache != null || voidReturnType ) // Skip if void return type or no InvocationCache has been defined.
         {
-            // Invoke method
-            return next.invoke( proxy, method, args );
-        }
-        catch( Exception e )
-        {
-            // Try cache
             String cacheName = method.getName();
             if( args != null )
             {
                 cacheName += Arrays.asList( args );
             }
-            Object result = cache.cachedValue( cacheName );
-            if( result != null )
+            try
+            {
+                // Invoke method
+                Object result = next.invoke( proxy, method, args );
+                // update cache
+                cache.setCachedValue( cacheName, result );
+                return result;
+            }
+            catch( Exception e )
             {
-                if( result == Void.TYPE )
-                {
-                    return null;
-                }
-                else
-                {
-                    return result;
-                }
+                // Try cache
+                return cache.cachedValue( cacheName );
             }
-            throw e;
         }
+        // if no InvocationCache is present.
+        return next.invoke( proxy, method, args );
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/SimpleInvocationCacheMixin.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/SimpleInvocationCacheMixin.java b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/SimpleInvocationCacheMixin.java
new file mode 100644
index 0000000..5897412
--- /dev/null
+++ b/libraries/invocation-cache/src/main/java/org/qi4j/library/invocationcache/SimpleInvocationCacheMixin.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2007 Rickard Öberg.
+ *
+ * Licensed  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.qi4j.library.invocationcache;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Simple implementation of InvocationCache.
+ * <p>
+ * This {@link InvocationCache} should typically not be used at all, and only serves as an
+ * example. The @{code cachedValues} member is never emptied, so it constitutes a memory leak
+ * if the method arguments keep changing.
+ * </p>
+ * <p>
+ * <b>IMPORTANT: Only use this is you know that only a small set of arguments are used into your
+ * method(s).</b>
+ * </p>
+ */
+public class SimpleInvocationCacheMixin
+    implements InvocationCache
+{
+    private final Map<String, Object> cachedValues = new ConcurrentHashMap<>();
+
+    @Override
+    public Object setCachedValue( String name, Object aResult )
+    {
+        return cachedValues.put( name, aResult );
+    }
+
+    @Override
+    public Object cachedValue( String name )
+    {
+        return cachedValues.get( name );
+    }
+
+    @Override
+    public Object removeCachedValue( String name )
+    {
+        return cachedValues.remove( name );
+    }
+
+    @Override
+    public void clearCachedValues()
+    {
+        cachedValues.clear();
+    }
+
+    @Override
+    public int currentCacheSize()
+    {
+        return cachedValues.size();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/c24b54ec/libraries/invocation-cache/src/test/java/org/qi4j/library/invocationcache/DocumentationSupport.java
----------------------------------------------------------------------
diff --git a/libraries/invocation-cache/src/test/java/org/qi4j/library/invocationcache/DocumentationSupport.java b/libraries/invocation-cache/src/test/java/org/qi4j/library/invocationcache/DocumentationSupport.java
new file mode 100644
index 0000000..782ce76
--- /dev/null
+++ b/libraries/invocation-cache/src/test/java/org/qi4j/library/invocationcache/DocumentationSupport.java
@@ -0,0 +1,51 @@
+/*
+ * 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.qi4j.library.invocationcache;
+
+import org.qi4j.bootstrap.AssemblyException;
+import org.qi4j.bootstrap.LayerAssembly;
+import org.qi4j.bootstrap.ModuleAssembly;
+import org.qi4j.bootstrap.layered.ModuleAssembler;
+
+public class DocumentationSupport
+{
+// START SNIPPET: composite
+    public interface ExpensiveOperation
+    {
+        @Cached
+        double compute( double... arguments );
+    }
+// END SNIPPET: composite
+
+// START SNIPPET: assembly
+    public class ExpensiveModuleAssembler
+        implements ModuleAssembler{
+
+        @Override
+        public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+            throws AssemblyException
+        {
+            module.services( ExpensiveOperation.class )
+                .withMixins( SimpleInvocationCacheMixin.class )
+                .withConcerns( ReturnCachedValueConcern.class );
+            return module;
+        }
+    }
+// END SNIPPET: assembly
+}


[3/3] zest-qi4j git commit: Adding some documentation to Locking library.

Posted by ni...@apache.org.
Adding some documentation to Locking library.


Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/4076eae3
Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/4076eae3
Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/4076eae3

Branch: refs/heads/develop
Commit: 4076eae35756a67b472d3f7c17e60a0426662203
Parents: 0553e80
Author: Niclas Hedhman <he...@betfair.com>
Authored: Thu Jul 9 11:44:51 2015 +0300
Committer: Niclas Hedhman <he...@betfair.com>
Committed: Thu Jul 9 11:44:51 2015 +0300

----------------------------------------------------------------------
 build.gradle                                    |  4 +-
 libraries/locking/dev-status.xml                |  2 +-
 libraries/locking/src/docs/locking.txt          | 39 +++++++++++++++++-
 .../qi4j/library/locking/ReadLockConcern.java   |  5 ++-
 .../qi4j/library/locking/WriteLockConcern.java  | 13 ++----
 .../library/locking/DocumentationSupport.java   | 42 ++++++++++++++++++++
 6 files changed, 88 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/4076eae3/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index a98aa00..126e4af 100644
--- a/build.gradle
+++ b/build.gradle
@@ -23,8 +23,8 @@ project.ext {
   testFailures = [ ]
   mainClassName = 'org.qi4j.container.Main'
   groovycMain_mx = "700m"
-  groovycMain_permSize = "256m"
-  groovycMain_maxPermSize = "256m"
+  groovycMain_permSize = "512m"
+  groovycMain_maxPermSize = "512m"
 }
 
 buildscript {

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/4076eae3/libraries/locking/dev-status.xml
----------------------------------------------------------------------
diff --git a/libraries/locking/dev-status.xml b/libraries/locking/dev-status.xml
index f8669b1..f549c99 100644
--- a/libraries/locking/dev-status.xml
+++ b/libraries/locking/dev-status.xml
@@ -24,7 +24,7 @@
     <codebase>stable</codebase>
 
     <!-- none, brief, good, complete -->
-    <documentation>none</documentation>
+    <documentation>brief</documentation>
 
     <!-- none, some, good, complete -->
     <unittests>some</unittests>

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/4076eae3/libraries/locking/src/docs/locking.txt
----------------------------------------------------------------------
diff --git a/libraries/locking/src/docs/locking.txt b/libraries/locking/src/docs/locking.txt
index a39f3c4..6f1f9ee 100644
--- a/libraries/locking/src/docs/locking.txt
+++ b/libraries/locking/src/docs/locking.txt
@@ -25,8 +25,43 @@
 source=libraries/locking/dev-status.xml
 --------------
 
-Locking Library
+The Locking Library is a simple way to mark method with Read or Write locks, and the details is handled by this
+library.
+
+This library is heavily used in EntityStore implementations.
 
-NOTE: This Library has no documentation yet. Learn how to contribute in <<community-docs>>.
 
 include::../../build/docs/buildinfo/artifact.txt[]
+
+The library creates a +java.util.concurrent.ReentrantReadWriteLock+ which is shared for all methods within the
+composite. It then acquires the read or write lock in a concern that is applied to the methods of the composite, which
+have the corresponding annotations.
+
+== +@ReadLock+ ==
+This annotation will apply the +ReadLockConcern+ to the method, and acquire the +lock.readLock()+ on entry and relase
+it on exit of the method. See the +ReentrantReadWriteLock+ for details on how/when to use it and the exact semantics.
+
+== +@WriteLock+ ==
+This annotation will apply the +WriteLockConcern+ to the method, and acquire the +lock.writeLock()+ on entry and relase
+it on exit of the method. See the +ReentrantReadWriteLock+ for details on how/when to use it and the exact semantics.
+
+== +LockingAbstractComposite+ ==
+This composite type is the easiest way to use this library. Simple extend you composite type interface with this
+interface and start marking the methods with the above annotations. No other complex assembly is required.
+
+[source,java]
+----
+public interface SomeService
+    extends ServiceComposite, LockingAbstractComposite
+{
+}
+----
+
+or apply it during assembly, in case that is the only choice (such as existing/external interfaces)
+
+[snippet,java]
+----
+source=libraries/locking/src/test/java/org/qi4j/library/locking/DocumentationSupport.java
+tag=assembly
+----
+

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/4076eae3/libraries/locking/src/main/java/org/qi4j/library/locking/ReadLockConcern.java
----------------------------------------------------------------------
diff --git a/libraries/locking/src/main/java/org/qi4j/library/locking/ReadLockConcern.java b/libraries/locking/src/main/java/org/qi4j/library/locking/ReadLockConcern.java
index 55c96a3..39e8a80 100644
--- a/libraries/locking/src/main/java/org/qi4j/library/locking/ReadLockConcern.java
+++ b/libraries/locking/src/main/java/org/qi4j/library/locking/ReadLockConcern.java
@@ -66,7 +66,7 @@ public class ReadLockConcern
      * Fix for this bug:
      * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6822370
      *
-     * @param lock
+     * @param lock the lock to be acquired.
      */
     protected void lock( Lock lock )
     {
@@ -74,7 +74,8 @@ public class ReadLockConcern
         {
             try
             {
-                while( !(lock.tryLock() || lock.tryLock( 1000, TimeUnit.MILLISECONDS )) )
+                //noinspection StatementWithEmptyBody
+                while( !lock.tryLock( 1000, TimeUnit.MILLISECONDS ) )
                 {
                     // On timeout, try again
                 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/4076eae3/libraries/locking/src/main/java/org/qi4j/library/locking/WriteLockConcern.java
----------------------------------------------------------------------
diff --git a/libraries/locking/src/main/java/org/qi4j/library/locking/WriteLockConcern.java b/libraries/locking/src/main/java/org/qi4j/library/locking/WriteLockConcern.java
index 956919a..f391667 100644
--- a/libraries/locking/src/main/java/org/qi4j/library/locking/WriteLockConcern.java
+++ b/libraries/locking/src/main/java/org/qi4j/library/locking/WriteLockConcern.java
@@ -44,7 +44,6 @@ public class WriteLockConcern
         throws Throwable
     {
         Lock writeLock = lock.writeLock();
-
         lock(writeLock);
         try
         {
@@ -52,14 +51,7 @@ public class WriteLockConcern
         }
         finally
         {
-            try
-            {
-                writeLock.unlock();
-            }
-            catch( Exception e )
-            {
-                e.printStackTrace();
-            }
+            writeLock.unlock();
         }
     }
 
@@ -73,7 +65,8 @@ public class WriteLockConcern
         {
             try
             {
-                while( !(lock.tryLock() || lock.tryLock( 1000, TimeUnit.MILLISECONDS )) )
+                //noinspection StatementWithEmptyBody
+                while( !lock.tryLock( 1000, TimeUnit.MILLISECONDS ) )
                 {
                     // On timeout, try again
                 }

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/4076eae3/libraries/locking/src/test/java/org/qi4j/library/locking/DocumentationSupport.java
----------------------------------------------------------------------
diff --git a/libraries/locking/src/test/java/org/qi4j/library/locking/DocumentationSupport.java b/libraries/locking/src/test/java/org/qi4j/library/locking/DocumentationSupport.java
new file mode 100644
index 0000000..c227bb7
--- /dev/null
+++ b/libraries/locking/src/test/java/org/qi4j/library/locking/DocumentationSupport.java
@@ -0,0 +1,42 @@
+/*
+ * 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.qi4j.library.locking;
+
+import org.qi4j.bootstrap.AssemblyException;
+import org.qi4j.bootstrap.LayerAssembly;
+import org.qi4j.bootstrap.ModuleAssembly;
+import org.qi4j.bootstrap.layered.ModuleAssembler;
+
+public class DocumentationSupport
+{
+// START SNIPPET: assembly
+    public class MyModuleAssembler
+        implements ModuleAssembler{
+
+        @Override
+        public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+            throws AssemblyException
+        {
+            module.services( MyService.class ).withTypes( LockingAbstractComposite.class );
+            return module;
+        }
+    }
+// END SNIPPET: assembly
+    public interface MyService {}
+}


[2/3] zest-qi4j git commit: Re-enable Test, since it now passes.

Posted by ni...@apache.org.
Re-enable Test, since it now passes.


Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/0553e80d
Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/0553e80d
Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/0553e80d

Branch: refs/heads/develop
Commit: 0553e80d478e89340fb77768fef1a568a17d6f6b
Parents: c24b54e
Author: Niclas Hedhman <he...@betfair.com>
Authored: Thu Jul 9 11:17:19 2015 +0300
Committer: Niclas Hedhman <he...@betfair.com>
Committed: Thu Jul 9 11:17:19 2015 +0300

----------------------------------------------------------------------
 .../qi377/InterfaceCollisionWithRelatedReturnTypesTest.java        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/0553e80d/core/runtime/src/test/java/org/qi4j/regression/qi377/InterfaceCollisionWithRelatedReturnTypesTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/qi4j/regression/qi377/InterfaceCollisionWithRelatedReturnTypesTest.java b/core/runtime/src/test/java/org/qi4j/regression/qi377/InterfaceCollisionWithRelatedReturnTypesTest.java
index d1741ac..35bf061 100644
--- a/core/runtime/src/test/java/org/qi4j/regression/qi377/InterfaceCollisionWithRelatedReturnTypesTest.java
+++ b/core/runtime/src/test/java/org/qi4j/regression/qi377/InterfaceCollisionWithRelatedReturnTypesTest.java
@@ -36,7 +36,7 @@ import static org.hamcrest.core.IsEqual.equalTo;
 import static org.hamcrest.core.IsNull.notNullValue;
 import static org.junit.Assert.assertThat;
 
-@Ignore( "This test exhibit QI-377" )
+//@Ignore( "This test exhibit QI-377" )
 public class InterfaceCollisionWithRelatedReturnTypesTest
     extends AbstractQi4jTest
 {