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

Reply via email to