Friday, April 11, 2008

Is it possible in MapListener? Yes, But...

It is interesting to find how Oracle Coherence is evolving and is being used to address some of the most critical problems of early 2000. The speed and areas it is being adopted I am not sure how long "It is not a database, It is not an Application server..." statement will hold true in future. The issues of Transaction integrity, multi-Table operations and off-loaded processing of yesteryears are now being done on Grid with operations spanning across multiple Caches with event driven architecture.
One common problem we deal with is when the Grid is being used by multiple independent applications but actions are to be performed based on events inside the Cache. Something like data needs to be put in Cache(2) based on an entry inserted in another Cache(1) by a different application. Similar to database events Coherence supports Map Listeners that listen to Cache events like Entry Inserted, updated or removed events. Following is a sample code:



NamedCache nCache = CacheFactory.getCache ("Cache1");
nCache.addMapListener (new MyListener ());

...
public class MyListener implements MapListener {
private NamedCache nCache = CacheFactory.getCache ("Cache2");

public void entryInserted (MapEvent m_event) {
Object key = ...;
Object value = ...;
nCache.put (key, value);
}
....
}



Now the fun part - Letting the Grid do it. What if Grid itself takes an action when an Entry is inserted, updated or deleted? Making Coherence Grid from an infrastructural resource to a self-contained processing unit. A "data oracle" that knows what it needs to do with data besides efficiently managing it. Now lets take a little detour here...
Who can listen to events? Someone who has "access" to where the events are happening, right? MapListeners that listen to Cache events can be added programatically to a Cache as shown above and can also be configured to listen to Backing Maps. Backing Maps are the components that manage data on each individual nodes of the cluster (one for each). In general mentioning a MapListener means the ones added to the NamedCache object. Listeners configured to listen to local events of Backing Maps are called Backing Map Listeners even though the same Listener instance can be used in either of the two. Backing Map Listeners can be configured in the coherence-cache-config.xml as shown below:


<read-write-backing-map-scheme>
<scheme-name>my-rw-bm</scheme-name>
<!-- unlimited capacity internal cache -->
<internal-cache-scheme>
<local-scheme>
</local-scheme>
</internal-cache-scheme>
<cachestore-scheme>
...
</cachestore-scheme>
<listener>
<class-scheme>
<class-name>MyListener</class-name>
</class-scheme>
</listener>
</read-write-backing-map-scheme>


With the above configuration MyListener instance on that node will listen to the local events generated by the backing map. The problem is now that the above implementation of MyListener will not work due to Thread issues. Multiple cache access can not be performed with in the same Thread which for BackingMap listener is an issue. To make this happen a separate Thread needs to be spawned from with in the MyListener to be able to access another Cache while listening to events from another.
So Yes, it is possible to do "that" what you want to do But, be a little careful.

No comments: