[jboss-cvs] JBossCache/docs/JBossCache-UserGuide/en/modules ...

Manik Surtani msurtani at jboss.com
Tue Jan 23 14:20:32 EST 2007


  User: msurtani
  Date: 07/01/23 14:20:32

  Modified:    docs/JBossCache-UserGuide/en/modules   configuration.xml
                        architecture.xml
  Log:
  Chapter 6
  
  Revision  Changes    Path
  1.5       +2 -2      JBossCache/docs/JBossCache-UserGuide/en/modules/configuration.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: configuration.xml
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/docs/JBossCache-UserGuide/en/modules/configuration.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -b -r1.4 -r1.5
  --- configuration.xml	23 Jan 2007 03:11:44 -0000	1.4
  +++ configuration.xml	23 Jan 2007 19:20:32 -0000	1.5
  @@ -61,7 +61,7 @@
         </para>
      </section>
   
  -   <section>
  +   <section id="configuration.options">
         <title>Overriding Configuration Options</title>
         <para>
            The Option API allows you to override certain behaviour of the cache on a per invocation basis.
  @@ -72,7 +72,7 @@
            <literal>Option</literal>
            object and passing it in the
            <literal>InvocationContext</literal>
  -         before invoking your method on the cache. More of this is discussed later.
  +         before invoking your method on the cache.
         </para>
         <para>
            See the javadocs on the
  
  
  
  1.3       +232 -52   JBossCache/docs/JBossCache-UserGuide/en/modules/architecture.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: architecture.xml
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/docs/JBossCache-UserGuide/en/modules/architecture.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -b -r1.2 -r1.3
  --- architecture.xml	23 Jan 2007 15:48:14 -0000	1.2
  +++ architecture.xml	23 Jan 2007 19:20:32 -0000	1.3
  @@ -1,90 +1,270 @@
   <chapter id="architecture">
      <title>Architecture</title>
      <section id="architecture.tree_structure">
  +      <title>How Your Data Is Organised</title>
   
  +
  +   <para>
  +      A <literal>Cache</literal> consists of a collection of <literal>Node</literal> instances, organised in a tree
  +      structure.  Each <literal>Node</literal> contains a <literal>Map</literal> which holds the data
  +      objects to be cached.  It is important to note that the structure is a mathematical tree, and not a graph; each
  +      <literal>Node</literal> has one and only one parent, and the root node is denoted by the constant fully qualitied name,
  +      <literal>Fqn.ROOT</literal>.
  +    </para>
  +    <para>
  +      The reason for organising nodes as such is to improve concurrent access to data and make replication and persistence
  +       more fine-grained.   
  +    </para>
  +    <para>
  +       <figure>
  +         <title>Data structured as a tree</title>
  +
  +         <mediaobject>
  +            <imageobject>
  +               <imagedata fileref="images/TreeCacheArchitecture.gif"/>
  +            </imageobject>
  +         </mediaobject>
  +      </figure>
  +
  +      In the diagram above, each box represents a JVM.  You see 2 caches in separate JVMs, replicating data to each other.
  +      These VMs can be located on the same physical machine, or on 2 different machines connected by a network link. The
  +      underlying group communication between networked nodes is done using <ulink url="http://www.jgroups.org">JGroups</ulink>.
  +   </para>
  +
  +   <para>Any modification (see <link linkend="api">API chapter</link>) in one cache instance will be replicated to
  +      the other cache.  Naturally, you can have more than 2 caches in a cluster.
  +      Depending on the transactional settings, this replication will occur either after each modification or at the
  +      end of a transaction, at commit time. When a new cache is created, it can optionally acquire the contents
  +      from one of the existing caches on startup.
  +   </para>
      </section>
   
      <section id="architecture.SPI_interfaces">
  +      <title>SPI Interfaces</title>
  +      <para>
  +         In addition to <literal>Cache</literal> and <literal>Node</literal> interfaces, JBoss Cache exposes more powerful
  +         <literal>CacheSPI</literal> and <literal>NodeSPI</literal> interfaces, which offer more control over the internals
  +         of JBoss Cache.  These interfaces are not intended for general use, but are designed for people who wish to
  +         extend and enhance JBoss Cache, or write custom <literal>Interceptor</literal> or <literal>CacheLoader</literal>
  +         instances.
  +      </para>
  +      <figure>
  +         <title>SPI Interfaces</title>
   
  +         <mediaobject>
  +            <imageobject>
  +               <imagedata fileref="images/SPI.png"/>
  +            </imageobject>
  +         </mediaobject>
  +      </figure>
  +      <para>
  +         The <literal>CacheSPI</literal> interface cannot be created, but is injected into <literal>Interceptor</literal> and <literal>CacheLoader</literal>
  +         implementations by the <literal>setCache(CacheSPI cache)</literal> methods on these interfaces.  <literal>CacheSPI</literal> extends <literal>Cache</literal>
  +         so all the functionality of the basic API is made available.
  +      </para>
  +      <para>
  +         Similarly, a <literal>NodeSPI</literal> interface cannot be created.  Instead, one is obtained by performing operations on <literal>CacheSPI</literal>,
  +         obtained as above.  For example, <literal>Cache.getRoot() : Node</literal> is overridden as <literal>CacheSPI.getRoot() : NodeSPI</literal>.
  +      </para>
  +      <para>
  +         It is important to note that directly casting a <literal>Cache</literal> or <literal>Node</literal> to it's SPI
  +         counterpart is not recommended and is bad practice, since the inheritace of interfaces it is not a contract
  +         that is guaranteed to be upheld moving forward.  The exposed public APIs, on the other hand, is guaranteed to
  +         be upheld.
  +      </para>
      </section>
   
      <section id="architecture.invocations">
  -
  +      <title>How Calls Are Invoked On The Data Structure</title>
  +      <para>
  +         Since the cache is essentially a collection of nodes, aspects such as clustering, persistence, eviction, etc.
  +         need to be applied to these nodes when operations are invoked on the cache as a whole or on individual nodes.
  +         To achieve this in a clean, modular and extensible manner, an interceptor chain is used.  The chain is built
  +         up of a series of interceptors, each one adding an aspect or particular functionality.  The chain is built
  +         when the cache is created, based on the configuration used.
  +      </para>
  +      <para>
  +         It is important to note that the <literal>NodeSPI</literal> offers some methods (such as the <literal>xxxDirect()</literal> method
  +         family) that operate on a node directly without passing through the interceptor stack.  Plugin authors should note
  +         that using such methods will affect the aspects of the cache that may need to be applied, such as locking,
  +         replication, etc.  Basically, don't use such methods unless you <emphasis>really</emphasis> know what you're doing!
  +      </para>
         <section id="architecture.interceptors">
  +         <title>Interceptors</title>
  +         <para>
  +            An <literal>Interceptor</literal> is an abstract class, several of which comprise an interceptor chain.  It
  +            exposes an <literal>invoke()</literal> method, which must be overridden by implementing classes to add behaviour
  +            to a call before passing the call down the chain by calling <literal>super.invoke()</literal>.
  +         </para>
  +         <figure>
  +         <title>SPI Interfaces</title>
   
  +         <mediaobject>
  +            <imageobject>
  +               <imagedata fileref="images/Interceptor.png"/>
  +            </imageobject>
  +         </mediaobject>
  +      </figure>
  +         <para>
  +            JBoss Cache ships with several interceptors, representing different configuration options, some of which are:
  +            <itemizedlist>
  +               <listitem><literal>TxInterceptor</literal> - looks for ongoing transactions and registers with transaction managers to participate in synchronization events</listitem>
  +               <listitem><literal>ReplicationInterceptor</literal> - replicates state across a cluster using a JGroups channel</listitem>
  +               <listitem><literal>CacheLoaderInterceptor</literal> - loads data from a persistent store if the data requested is not available in memory</listitem>
  +            </itemizedlist>
  +            The interceptor chain configured for your cache instance can be obtained and inspected by calling <literal>CacheSPI.getInterceptorChain()</literal>,
  +            which returns an ordered <literal>List</literal> of interceptors.
  +         </para>
  +         <section id="architecture.custom_interceptors">
  +            <title>Writing Custom Interceptors</title>
  +            <para>
  +               Custom interceptors to add specific aspects or features can be written by extending <literal>Interceptor</literal> and overriding
  +               <literal>invoke()</literal>.  The custom interceptor will need to be added to the interceptor chain by using the
  +               <literal>CacheSPI.addInterceptor()</literal> method.
  +            </para>
  +            <para>
  +               Adding custom interceptors via XML is not supported at this time.
  +            </para>
  +         </section>
         </section>
   
         <section id="architecture.methodcalls">
  -
  +         <title>MethodCalls</title>
  +         <para>
  +            <literal>org.jboss.cache.marshall.MethodCall</literal> is a class that encapsulates a <literal>java.lang.reflection.Method</literal>
  +            and an <literal>Object[]</literal> representing the method's arguments.  It is an extension of the <literal>org.jgroups.blocks.MethodCall</literal>
  +            class, that adds a mechanism for identifying known methods using magic numbers and method ids,
  +            which makes marshalling and unmarshalling more efficient and performant.
  +         </para>
  +         <para>
  +            This is central to the <literal>Interceptor</literal> architecture, and is the only parameter passed in to
  +            <literal>Interceptor.invoke()</literal>.
  +         </para>
         </section>
   
         <section id="architecture.invocationcontext">
  -
  -      </section>
  -
  -      <section id="architecture.custom_interceptors">
  -
  +         <title>InvocationContexts</title>
  +         <para>
  +            This context is one that holds intermediate state for the duration of a single invocation, and is set up and
  +            destroyed by the <literal>InvocationContextInterceptor</literal> which sits at the start of the chain.
  +         </para>
  +         <para>
  +            The purpose of the <literal>InvocationContext</literal> is to hold information about a call, such as
  +            any <literal>javax.transaction.Transaction</literal> or <literal>org.jboss.cache.transaction.GlobalTransaction</literal>
  +            objects associated with a call, including invocation information such as <literal>InvocationContext.isOriginLocal()</literal>.
  +         </para>
  +         <para>
  +            The <literal>InvocationContext</literal> is also where <literal>Option</literal> objects can be added to specify
  +            single-invocation configuration overrides.  More about this subject in the <link linkend="configuration.options">configuration chapter</link>.
  +         </para>
  +         <para>
  +            The <literal>InvocationContext</literal> can be obtained by calling <literal>Cache.getInvocationContext()</literal>.
  +         </para>
         </section>
  -
      </section>
   
      <section id="architecture.managers">
  -
  -      <section id="architecture.transactionmanager">
  -
  -      </section>
  +      <title>Managers For Subsystems</title>
  +      <para>
  +         Some aspects and functionality is shared by more than a single interceptor.  Some of these have been encapsulated
  +         into managers, for use by various interceptors, and are made available by the <literal>CacheSPI</literal> interface.
  +      </para>
   
         <section id="architecture.rpcmanager">
  -
  +         <title>RpcManager</title>
  +         <para>
  +            This class is responsible for calls made via the JGroups channel for all RPC calls to remote caches, and
  +            encapsulates the JGroups channel used.
  +         </para>
         </section>
   
         <section id="architecture.buddymanager">
  -
  +         <title>BuddyManager</title>
  +         <para>
  +            This class manages buddy groups and invokes group organisation remote calls to organise a cluster of
  +            caches into smaller sub-groups.
  +         </para>
         </section>
   
         <section id="architecture.cacheloadermanager">
  -
  +         <title>CacheLoaderManager</title>
  +         <para>
  +            Sets up and configures cache loaders.  This class wraps individual <literal>CacheLoader</literal> instances
  +            in delegating classes, such as <literal>SingletonCacheLoader</literal> or <literal>AsyncCacheLoader</literal>,
  +            or may add the <literal>CacheLoader</literal> to a chain using the <literal>ChainingCacheLoader</literal>.
  +         </para>
         </section>
   
  -
      </section>
   
      <section id="architecture.marshalling">
  -
  -   </section>
  -
  -
  -
  -
  +      <title>Marshalling And Wire Formats</title>
  +      <para>
  +         Early versions of JBoss Cache simply wrote cached data to the network by writing to an <literal>ObjectOutputStream</literal>
  +         during replication.  Over various releases in the JBoss Cache 1.x.x series this approach was gradually deprecated
  +         in favour of a more mature marshalling framework.  In the JBoss Cache 2.x.x series, this is the only officially
  +         supported and recommended mechanism for writing objects to datastreams.
  +      </para>
      <figure>
  -      <title>Schematic TreeCache architecture</title>
  +         <title>The Marshaller interface</title>
   
         <mediaobject>
            <imageobject>
  -            <imagedata fileref="images/TreeCacheArchitecture.gif"/>
  +               <imagedata fileref="images/Marshaller.png"/>
            </imageobject>
         </mediaobject>
      </figure>
  +      <section>
  +         <title>The Marshaller Interface</title>
  +         <para>
  +            The <literal>Marshaller</literal> interface extends <literal>RpcDispatcher.Marshaller</literal> from JGroups.
  +            This interface has two main implementations - a delegating <literal>VersionAwareMarshaller</literal> and a
  +            concrete <literal>CacheMarshaller200</literal>.
  +         </para>
  +         <para>
  +            The marshaller can be obtained by calling <literal>CacheSPI.getMarshaller()</literal>, and defaults to the <literal>VersionAwareMarshaller</literal>.
  +            Users may also write their own marshallers by implementing the <literal>Marshaller</literal> interface and
  +            adding it to their configuration, by using the <literal>MarshallerClass</literal> configuration attribute.
  +         </para>
  +      </section>
   
  -   <para>The architecture is shown above. The example shows 2 Java VMs, each
  -      has created an instance of
  -      <literal>TreeCache</literal>
  -      . These VMs can be located on the same
  -      machine, or on 2 different machines. The setup of the underlying group
  -      communication subsystem is done using
  -      <ulink url="http://www.jgroups.org">JGroups</ulink>
  -      .
  -   </para>
  -
  -   <para>Any modification (see API below) in one cache will be replicated to
  -      the other cache
  -      <footnote>
  -         <para>Note that you can have more than 2 caches in a cluster.</para>
  -      </footnote>
  -      and vice versa. Depending on the transactional settings, this replication will occur either after each
  -      modification or at the end of a transaction (at commit
  -      time). When a new cache is created, it can optionally acquire the contents
  -      from one of the existing caches on startup.
  +      <section>
  +         <title>VersionAwareMarshaller</title>
  +         <para>
  +            As the name suggests, this marshaller adds a version <literal>short</literal> to the start of any stream when
  +            writing, enabling similar <literal>VersionAwareMarshaller</literal> instances to read the version short and
  +            know which specific marshaller implementation to delegate the call to.
  +            For example, <literal>CacheMarshaller200</literal>, is the marshaller for JBoss Cache 2.0.x.
  +            JBoss Cache 2.1.x, say, may ship with <literal>CacheMarshaller210</literal> with an improved wire protocol.
  +            Using a <literal>VersionAwareMarshaller</literal> helps achieve wire protocol compatibility between minor
  +            releases but still affords us the flexibility to tweak and improve the wire protocol between minor or micro releases.
  +         </para>
  +
  +      </section>
  +
  +      <section>
  +         <title>CacheMarshaller200</title>
  +         <para>
  +            This marshaller treats well-known objects that need marshalling - such as <literal>MethodCall</literal>,
  +            <literal>Fqn</literal>, <literal>DataVersion</literal>, and even some JDK objects such as <literal>String</literal>,
  +            <literal>List</literal>, <literal>Boolean</literal> and others as types that do not need complete class definitions.
  +            Instead, each of these well-known types are represented by a <literal>short</literal>, which is a lot more efficient.
      </para>
  +         <para>
  +            In addition, reference counting is done to reduce duplication of writing certain objects multiple times, to help
  +            keep the streams small and efficient.
  +         </para>
  +         <section>
  +            <title>JBoss Serialization</title>
  +            <para>
  +               Types that the marshaller does not know or care about are serialized using the highly efficient
  +               <ulink url="http://labs.jboss.com/portal/serialization">JBoss Serialization</ulink> library.  This adds
  +               <literal>jboss-serialization.jar</literal> as a dependency, but can be disabled by adding the following
  +               JVM argument <literal>-Dserialization.jboss=false</literal>.  In this case serialization of unknown types
  +               will fall back to standard Java serialization.
  +            </para>
  +            </section>
  +      </section>
   
  +   </section>
   </chapter>
  \ No newline at end of file
  
  
  



More information about the jboss-cvs-commits mailing list