Hello, I've just commited a generic cache-invalidation mechansim to HEAD (mainly in org.jboss.cache.invalidation). Some of the code and ideas comes from Bill Burke's implementation of the Seppuku algorithm that has been recently commited.
It allows to have any cache to be invalidated by any resource. In addition, Plugins allows to have distributed-cache-invalidations (cluster for example). Invalidations can come from an external process or be send to an external process (or both). Full integration of this generic service with JBoss entity beans has been implemented as well. Design ====== Each JVM has an *InvalidationManager* (IM) (it could have more). Each IM will manage invalidation-events and subscriptions from two kinds of actors: - Local caches and invalidators - Plugins InvalidationGroup ================= Caches that share invalidations messages (i.e. that represent the same data), share a common *InvalidationGroup* (IG). Examples: 1) if you deploy your bean twice: once for RW access in commit option C and once for RO access in commit option A with other optimisations, both EJB represent the same underlying data => they live in the same InvalidationGroup 2) An EJB that is deployed on two nodes of a cluster live in the same InvalidationGroup: a modification made on a bean on node 1 must be invalidated from the cache of the same EJB on node 2. The IM is able to invalidate one key, a set of keys or a set of keys for a set of InvalidationGroups in a single shot, thus minimizing network cost (when using a bridge) and allowing to group all invalidations happening in a single transaction and involving more thant one cache so that they are propagated in a single shot. When a new IG is created, it is represented as an (dynamic) MBean => it is accessible through JMX for invalidation or any other action (statistics could be added for example) Local Caches ============ A cache, will get access to the local InvalidationManager and will subscribe using an appropriate InvalidationGroup (i.e. shared identifier, name). Whenever an invalidation message is received by the IM for this IG, the cache will receive a callback. Caches and related object must implement the *Invalidable* interface. EJB: An extension of the EntityInstanceCache has been implemented that hook up in the cache-invalidation mechanism: InvalidableEntityInstanceCache. Configuration information is explained below. Invalidator =========== Invalidators (i.e. an interceptor for example) subscribe to the local IM and can send invalidation messages (single key, set of keys or set of keys for a set of groups). Each invalidation is sent to the subscribed Invalidable objects AND to the registered plugins (more info below) EJB: An invalidator for EB has been implemented as an interceptor in EntityBeanCacheBatchInvalidatorInterceptor in the package org.jboss.cache.invalidation.triggers. It will not only send invalidation messages, but will also group them so that they are only broadcast at transaction-commit-time. For this, it uses the org.jboss.cache.invalidation.InvalidationsTxGrouper helper class. Bridges ======= Bridges are IM plugins are not linked to a specific IG but, instead, receive all invalidations and are able to send invalidations messages for any IG. They generally bridge several IM running on distant nodes, but other usage can be imagined such as providing a protocol-friendly gateway to an IM for a client running in a Javaless environnement (DB trigger that would only do HTTP invocations for example). When an invocation is sent through a bridge for a given IG, it is sent to every Invalidable object registered to this IG AND to all other bridges linked to this IM (except the source-bridge of course) Two bridge implementations have been implemented: JavaGroups-based (in the cluster module) and JMS-based. Note that several instances of a given bridge can be started at the same time on the same node and linked to any present IM. JMS-Bridge ========== This simple bridge sends and receives invalidations messages through a given JMS Topic. All invalidations messages are send to this JMS topic, without filtering the content. The bridge can be configured to ONLY send invalidations messsages, ONLY receive invalidations messages or BOTH: this is interesting for application that want to communicate with the IM through JMS but are not interested in receiving the invalidations that comes from this this IM. (bridge not really tested yet.) JavaGroups-Bridge ================= This bridge sends and receives invalidations messages through JavaGroups. NOT all invalidation messages are sent: each bridge will dynamically discover other bridges running in the cluster (with the same bridge name) and ask them for the list of IG that they have locally. Thus, the bridge will only forward invalidation messages targetting IG that exist on remote nodes. This information is dynamically recomputed when the cluster-topology changes or when new IG are created/dropped on nodes of the cluster. Furthermore, invalidations can be forwarded synchronously or asynchronously, depending on the invalider choice. Tested. Configuration ============= By default: - the "default" config starts an InvalidationManager (and contain the config for a JMS-bridge in comments) - the "all" config starts an InvalidationManager and the JG-Bridge EJB: ==== To use the cache invalidation mechanism with your EB, you first need to use the appropriate config. One has been created in standardjboss.xml: "Standard CMP 2.x EntityBean with cache invalidation". Thus, you first need to modify your jboss.xml file to use this configuration. (See "PROPOSAL" below for more info) Then, for each EB, you need to activate the registration to the local IM by using the appropriate "cache-invalidation" tag: <jboss> <enterprise-beans> <entity> <ejb-name>SimpleEJB</ejb-name> <configuration-name>Standard CMP 2.x EntityBean with cache invalidation</configuration-name> *** <cache-invalidation>True</cache-invalidation> </entity> </enterprise-beans> </jboss> Note: if set to True, the interceptor will forward invalidations, no matter what is the current commit option of the container. Note 2: if set to true, the cache will only subscribe for invalidation messages if the container runs in CO A or D. At this point, the container will itself decide what is the name of the InvalidationGroup by taking the EJB name and will use the default InvalidationManager instance. If what you are trying to achieve is cluster-wise invalidation of cache, then that is fine because the EJB name will be the same on all nodes, and consequently all EJBs will share the same IG. But if what you want to achieve is to have two identical EJBs running in the same JBoss instance that invalidate their respective cache, they will not belong to the same IG because each EJB will have its own name. Thus, you need in this case to assign the same IG name to both EJBs: <jboss> <enterprise-beans> <entity> <ejb-name>SimpleEJB</ejb-name> <configuration-name>Standard CMP 2.x EntityBean with cache invalidation</configuration-name> <cache-invalidation>True</cache-invalidation> *** <cache-invalidation-config> *** <invalidation-group-name>MY_IG_FOR_SIMPLE_EJB</invalidation-group-name> *** </cache-invalidation-config> </entity> <entity> <ejb-name>SimpleEJB-Replica</ejb-name> <local-jndi-name>cmp2/simple/Simple</local-jndi-name> *** <cache-invalidation-config> *** <invalidation-group-name>MY_IG_FOR_SIMPLE_EJB</invalidation-group-name> *** </cache-invalidation-config> <cache-invalidation>True</cache-invalidation> </entity> </enterprise-beans> </jboss> Thus, by default, only setting the cache-invalidation tag to true is enough (and starting at least a bridge) to get distributed-cache-invalidations! PROPOSAL: ========= Currently, only one EB container configuration has been written in standardjboss.xml (CMP 2.0 non-clustered). To satisfy all scenarios, we would have to duplicate all EB container config: cmp 1.1, CMP 2.0, bmp, clustered-xxx, etc.. This makes an administration nightmare. Do you mind if I had the new interceptor + cache to all the existing EB container config? Consequences: - if the cache-invalidation is set to False, the interceptor is a no-op interceptor and the new code in the invalidable cache is never used (not even registered in the IM) - the code of the cache is not new: it only extends the currently-used cache (if you fear new bugs) - if no InvalidationManager is started and <cache-invalidation> is set to False (or not set at all, as False is the default), the EB container will start without any problem/exception: thus the current behaviour is kept and there is no need to start an additional InvalidationManager if you don't need it. Cheers, Sacha ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-development