I need a simple cache API for use in the XTags tag library and I can imagine
it being quite useful elsewhere. So over the next week or so I'd like to
work on a cache project in Jakarta-Commons if there are no objections. (It
may give me a good use case to experiment with the MetaFactory project at
the same time).

There is currently a JCache JSR (107) to define a caching specification,
which seems some way off delivering anything open source so the idea being
that the "cache" project in Jakarta-Commons would be a simple, stripped down
implementation of what JCache may become one day.

As Jon Stevens pointed out on the JSR 107 (JCache) mail list, it is worth
evaluating the current caching technology available in the current Jakarta
projects first (e.g. Turbine / Avalon etc.) before any work should commence.

I'll try use the spirit of the current JCache proposal though it will be
much a simpler, trimmed down API. (Since I've never seen any of Oracles
source code there can be no copyright issues).

I just wanted to run the idea past this list first before I dive into
reading code & maybe putting an API together.

The API will be that of a local JVM cache of objects. The user is blissfully
unaware if there is any distributed replication (or group flushing) policy
across cache instances. It will use a similar mechanism to log4j where a
'region' of the cache could be looked up in application code and then used
efficiently, rather like log4j Category objects.

Using a variety of deployment descriptor XML documents (or properties files
et al) and implementatation techniques different regions of the cache can
behave in different ways, use different implementations (local, remote,
synchronized, LRU / SoftReference / fixed size etc.)

So pseudo code would look something like this...

public class Foo {

    protected static final CacheRegion cache
        = Cache.getRegion( "com.acme.FooCache", new MyCacheLoader() );

    public void doSomething( String someURL ) {
        // let's lookup an XML Document

        Document document = (Document) cache.get( someURL );

        assert( "it won't ever be null", document != null );
    }
}

The CacheLoader interface is something along these lines...

public interface CacheLoader {

    public Object
d( 
        Object key, 
        Object optionalArguments 
    ) throws Exception;
}

So, once you've got a CacheRegion you don't need to worry about synchronization or 
anything, its a single line of code to extract stuff from the cache. Notice that when 
you lookup the CacheRegion you supply a CacheLoader object to be used to load items 
that are not in the cache.

Sometimes the key to the cache may not be enough information to make the 'object' in 
the cache, so the get method may take a reference to a CacheLoader which is capable of 
creating the object if its not in the cache. (This saves the application developer 
testing for null, creating the object and adding it into the cache such that the Cache 
can do optimum locking to avoid 'object recreation storms' and doing proper, efficient 
synchronization etc.)

So if your Bar class had some state that may help it to recreate an object for a 
certain key you could do something like


public Bar implements CacheLoader {

    protected static final CacheRegion cache = Cache.getRegion( "myBarCache" );

    public void doSomething(Object key) {
        // pass myself (this) in as the key
        // in case I need to create a new Foo

        Foo foo = (Foo) cache.get( key, this );
        ...
    }

    // CacheLoader API...

    public Object load( Object key, Object optionalArguments ) {
        // use my state to create an object for the given key
        ...
    }
}


Where "this" CacheLoader is passed into the CacheRegion which is used to create a new 
item in the cache if its not there.

This allows the CacheLoader to not have to worry about handling exceptions - the 
CacheRegion can catch them and call a handler. e.g. so if it is a database object, the 
cache may retry N tim
es until the cache loader succeeds before aborting, logging the exception
somewhere or whatever.


Sound like a reasonable idea?

James




_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

Reply via email to