

Refactoring of the TreeCache
============================

Revision: $Id: Refactoring.txt,v 1.1.4.1 2004/12/14 08:18:57 starksm Exp $


Available interceptors
----------------------

* ReplicationInterceptor:
Replicates synchronously or asynchronously. When TX: replicate on TX commit (2PC in case of sync repl)

* CacheLoaderInterceptor:
Loads element not in the cache from a CacheLoader, on the way in

* CacheStoreInterceptor
Store modifications back to the CacheLoader, on the way out. If non-transactional, does this after each method call,
otherwise at TX commit

* CreateIfNotExistsInterceptor
Creates a new node if it doesn't exist on put() methods

* LockInterceptor
Performs locking, acquires and release before/after each method if non-transactional, otherwise releases at TX commit

* CallInterceptor
Performs the actual call on the JBossCache






Example scenario
----------------

1. Shared store

       JBossCache (A)                               JBossCache (B)

      CallInterceptor                              CallInterceptor

      LockInterceptor                              LockInterceptor

 CreateIfNotExistsInterceptor                CreateIfNotExistsInterceptor

   [CacheLoaderInterceptor]                     [CacheLoaderInterceptor (loads on the way in)]

                            (replication)
  [ReplicationInterceptor]  <-----------------  [ReplicationInterceptor]

  [CacheStoreInterceptor]                        [CacheStoreInterceptor (stores on the way out)]

                                                          ^
                                                          |
                                                          | (incoming method call)


JBossCache A and B are 2 nodes in a cluster.
In this case, node B gets an operation, e.g. put(). Its CacheLoaderInterceptor stores the modification in the store,
and its ReplicationInterceptor replicates the call to node A, where the change is applied to the cache (but not
the CacheLoader !). Both ReplicationInterceptors then pass the call on to their respective caches.
The result here is that only the node where the change is made (node B) actually stores to the backend store.


2. Unshared store


      JBossCache (A)                               JBossCache (B)

      CallInterceptor                              CallInterceptor

     LockInterceptor                              LockInterceptor

 CreateIfNotExistsInterceptor                CreateIfNotExistsInterceptor

  [CacheStoreInterceptor]                      [CacheStoreInterceptor (stores on the way out)]

  [CacheLoaderInterceptor]                      [CacheLoaderInterceptor (loads on the way in)]

                            (replication)
  [ReplicationInterceptor]  <-----------------   [ReplicationInterceptor]

                                                          ^
                                                          |
                                                          | (incoming method call)


In this scenario, both nodes have their own local store. The call is intercepted at node B, which replicates
it across the cluster. Since CacheLoaderInterceptor is now *above* ReplicationInterceptor, rather than *below*,
the modification will be store in *both* local stores (A and B).
We can therefore provide a (1) shared store and (2) unshared store scenario by just configuring the
interceptor chain differently