### Invocation Cache

code

docs

tests

The Invocation Cache Library provides constructs to easily cache the return value of method invocations on composites.

### Note

It has nothing to do with the Cache SPI.

Table 34. Artifact

Group ID | Artifact ID | Version
--- | --- | ---
org.qi4j.library | org.qi4j.library.invocation-cache | 2.1

By applying one of the 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 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.

    public interface ExpensiveOperation
    {
        @Cached
        double compute( double... arguments );
    }

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.

    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;
        }
    }

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 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

    @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.