Based on the feedback we have received here we have created a draft of an API for an event framework.
The semantics of the system that we have outlined are: * There are two kinds of events - Database Lifecycle Events and Transaction Events * The interesting Lifecycle events are: - "before shutdown", to enable shutting down services cleanly that depend on the GraphDatabaseService - An event that gets triggered when the GraphDatabaseService has entered a state from which it cannot recover, we'ce called this event "kernel panic". * We could identify another lifecycle event: "after startup", but we couldn't find a case where an event handler could be installed when this event would be fired, since event handlers would be registered after the the GraphDatabaseService has been instantiated. * The minimal number of interesting Transaction events we have identified are: - "before commit": invoked when a transaction is about to be committed. - "after commit": invoked after the transaction has successfully been committed - "after rollback": invoked if the transaction could not be committed, after it has been rolled back. * All Transactional events are synchronous, i.e. they are invoked in the same thread as the transaction is performed in. * The "after commit" and "after rollback" events are only invoked if "before commit" already been invoked. * The first argument of all Transactional event handling methods is an object that contains all the state that was modified during the transaction. * When "before commit" is invoked the transaction is still open, meaning that it would be possible to modify the graph as part of the handling of the event. There are however no guarantees that these modifications will be seen by other (and even the same) event handlers, therefore it is strongly discouraged to modify the graph during the handling of the event. The only guarantee is that the events will not be reissued, i.e. the event handlers will not be invoked again. * If the handling of "before commit" throws an exception (any exception) the transaction will fail and be rolled back, invoking the "after rollback" method of all the handlers that have had their "before commit" handler invoked, except for the handler that threw the exception. * If a transaction is marked for rollback [tx.failure()] before it is completed [tx.finish()], the Transaction event handler is never invoked (actually if the transaction is *not* marked as successful). * Since Transactional event handlers are used concurrently from multiple threads they should be stateless. In order to be able to carry state from the "before commit" event to the "after commit" or "after rollback" events, the "before commit" method may return an arbitrary object that will be passed as a second argument to the handler methods for "after commit" or "after rollback". We have opted for only implementing synchronous pro-active bulk operation events since they can be used to emulate any other kind of events. This decision was made based on the input in this thread of using an existing event dispatch system. It is easy for the user to based on the events defined above fire off events through another event dispatch system. * Equivalent reactive asynchronous events are simple. * Reactive asynchronous events for each individual change that occurred could be constructed from the transaction change data that is passed to the event handler methods. * It would even be possible (but a bad idea) to fire of further synchronous events. The code of the API draft is available for checkout at: https://svn.neo4j.org/laboratory/components/event-framework/ A browsable version is available at: https://trac.neo4j.org/browser/laboratory/components/event-framework/src/main/java/org/neo4j/event/ Please let us know what you think! Cheers, -- Tobias Ivarsson <tobias.ivars...@neotechnology.com> Hacker, Neo Technology www.neotechnology.com Cellphone: +46 706 534857 _______________________________________________ Neo mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user