Proposal for JBoss Cache events
twundke Jan 21, 2005 1:36 AMBela and Ben,
I'd like to put forward an idea for JBoss Cache. However, first let me describe what I'm doing.
I have a distributed application that uses JBoss Cache to distribute data to all nodes. I'm using AOP for all cache access, synchronous replication, transactions with read committed locking and separate file-based cache loaders. The application is also standalone, with no application server etc.
Now, to my current problem. The application is event-driven, so when updating an object I want to send an event to my event manager on each node. The ordering of events is also important, so each local event manager should receive events in the same order.
What I'd like to propose is that the cache have the ability to associate an event with a transaction, and on commit that event will be propagated by the replication manager, and then sent to some local class via an interface. Now, ordinarily I wouldn't propose this as something that a cache should do, but with the use of AOP it becomes more important. It's ultimately AOP that allows me to write my application the way I have (and it's a great mechanism for data distribution!), but the lack of object-based event handling, as opposed to Node-based events (ie. the TreeCacheListener) is limiting.
I've had a good look through the code, and have scraped together something that works, just to demonstrate to myself that it can be done. However, obviously it needs to be discussed with you guys in order to find an appropriate way to integrate it into the current structure (or even at all, although I'm really hoping that you guys allow this to happen! :-).
Here's a rough overview of what I did to get it working.
TransactionEntry.java
- Add an Event attribute that has associated set() and get() methods.
TransactionTable.java
- Add set() method for Event.
EventReceiver.java *new*
- An interface defining eventReceived(Event) that is called when an event is generated after commit.
EventInterceptor.java *new*
- Registers a synchronisation handler in invoke() if there's a transaction.
- In afterCompletion(), if we're committing then it retrieves the event and calls EventReceiver.eventReceived(Event).
TreeCache.java
- Add set() and get() methods for the EventReceiver
- Add the EventInterceptor into the chain just before CallInterceptor. It needs to be higher
than ReplicationInterceptor so that it gets called on the remote nodes.
ReplicationInterceptor.java
- In beforeCompletion(), adds the event to the argument list of the remote prepare method.
- In replicate(), extracts the event and passes it to handlePrepare().
- In handlePrepare(), sets the event into the transaction entry.
Currently I just set the event by calling TreeCache.getTransactionTable().setEvent( treeCache.getCurrentTransaction(), myEvent ). This would obviously change.
So, what are your thoughts on this whole idea? I'm happy to take this offline if you want to discuss it further, although I guess this is actually the "development" forum :-)
Note that I'm also volunteering to write all of the code for this. I'm not asking you guys to do that :-)
Tim