[jbosscache-dev] Re: [javagroups-users] Considering migrating to jboss cache from DistributedTree

Brian Stansberry brian.stansberry at redhat.com
Thu Apr 12 11:11:02 EDT 2007


Thanks much for this, Bill.  Sorry for the slow reply.  I'm going to 
wait and let Manik Surtani comment on this, as I know he's thought a lot 
more than I have about how he wants the factories and the CacheImpl 
constructor to work.

Bill Middleton wrote:
> Thanks for the encouraging reply, Brian.  My followup is inline, and 
> there's a proposed patch at the end.
> 
> Bill
> 
> On 4/6/07, *Brian Stansberry* < brian.stansberry at redhat.com 
> <mailto:brian.stansberry at redhat.com>> wrote:
> 
>     Bill Middleton wrote:
>      > A cursory (and likely naive) inspection of DefaultCacheFactory and
>      > CacheImpl seems to indicate that providing my own channel should be
>      > fairly easy to implement, even if an extension won't quite get
>     the job
>      > done, since channel is private.  The intimidating part is the binding
>      > between the "official" multiplexed channel (mbean) and other
>      > functionality which implies a full app-server, such as the
>      > TransactionManager.
> 
>     Not sure what you mean here by "binding". Passing a JChannelFactoryMBean
>     to the RuntimeConfig doesn't carry with it a requirement to pass in a
>     TransactionManager. Think of RuntimeConfig as basically being a
>     placeholder through which the external environment can pass in complex
>     objects the cache may need and through which callers can get access to a
>     few of the cache internals.
> 
> 
> Every test I run does insist upon looking for a TransactionManager, if 
> one isn't found then a DummyTransactionManager is the "fall back" 
> solution.  Granted though, it's not bound to an app server. 
> 
>      > If I were to pass in a channel to CacheImpl,
>      > whether multiplexed or not, I don't think I'll mess with
>      > setUsingMultiplexer() and friends in the Configuration. Since I'm
>     going
>      > to manage the muliplexer functionality myself I guess it makes
>     sense to
>      > let Cache think that it's just a simple channel.  This seems safe
>      > enough, I hope.
>      >
> 
>     Sure, as long as in reality it's a multiplexed channel, so the cache
>     doesn't get messages it won't understand. If you're writing your own
>     extensions, then presumably you know how the code will be used and can
>     guard against misuse. So, the barrier for what's considered "safe" can
>     be a lot lower. :)
> 
> 
> My proposed patch doesn't require a multiplexed channel be passed in.  
> The implementation can pass in either an ordinary JChannel (via new 
> JChannel()) or one that's created via createMultiplexerChannel().  All 
> of the state transfer tests pass in either case.  In neither case is the 
> Configuration set using setUsingMultiplexer(true). isUsingMultiplexer is 
> always false.  Seems to work ok - all tests pass using an adapted 
> StateTransferCompatibilityTest.java, anyhow.
> 
> Generally, my patch adds a new constructor, CacheImpl(Channel c).  This 
> is called by a new createChannel() method in the DefaultChannelFactory 
> which accepts a channel, configuration, and boolean.  If the new 
> constructor is used to construct a ChannelImpl, then a global boolean is 
> set which makes the create() method do the right thing at init-time. 
> 
> Is this approach way too simple minded?  It's not providing any 
> additional access to the internals of the cache per se, but yes, one 
> must be careful in configuring the channel.  Whats still missing here is 
> the ability to fetch the entire Element <protocol_stacks> from the 
> Configuration and pass it directly to the JChannelFactory(Element) 
> constructor, so that the external JGroups stack would be guaranteed to 
> match the one which is specified in the config.
> 
> 
> Bill
> 
> PS -  sorry about the indentation in the patch, Eclipse cant quite 
> figure out the scheme that jbosscache is using.
> 
> 
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> ? patch
> Index: CacheFactory.java
> ===================================================================
> RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/CacheFactory.java,v
> retrieving revision 1.7
> diff -r1.7 CacheFactory.java
> 11a12
>> import org.jgroups.Channel;
> 111a113,131
>>    /**
>>     * Creates {@link Cache} instance, by passing in a pre-configured {@link org.jgroups.JChannel}
>>     * and optionally starts it based on the boolean start value.  The new cache's configuration
>>     * will be based on a {@link org.jboss.cache.config.Configuration} passed in.
>>     * <p/>
>>     * Ensure that the Configuration you pass in is not used by another cache instance in the same JVM,
>>     * as it may be concurrently modified. Clone the configuration, if shared, using
>>     * {@link org.jboss.cache.config.Configuration#clone()}.
>>     *
>>     * @param configuration the {@link org.jgroups.JChannel} to use (cast to simple channel).
>>     * @param configuration the {@link Configuration} object that is passed in to setCache the {@link Cache}.
>>     * @param start         if true, the cache is started before returning.
>>     * @return an optionally running {@link Cache} instance
>>     * @throws org.jboss.cache.config.ConfigurationException
>>     *          if there are problems with the configuration
>>     */
>>    Cache<K, V> createCache(Channel ch, Configuration configuration, boolean start) throws ConfigurationException;
>>
> Index: CacheImpl.java
> ===================================================================
> RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/CacheImpl.java,v
> retrieving revision 1.57
> diff -r1.57 CacheImpl.java
> 238c238,245
> < 
> ---
>>    
>>    /**
>>     * Have we gotten a channel passed in from the
>>     * implementation?  We set this to false in the
>>     * constructor if so.  Ordinarily isMyChannel is always true.
>>     */
>>    private boolean isMyChannel = true;
>>    
> 260a268,282
>>    /**
>>     * Constructs an uninitialized CacheImpl with a provided channel
>>     */
>>    protected CacheImpl(Channel ch) throws Exception
>>    {
>> 	  isMyChannel = false; 
>> 	  if(ch instanceof JChannel){
>> 		  channel = (JChannel)ch; 
>> 	  }
>> 	  else{
>> 		  throw new Exception("Not a JChannel!");
>> 	  }
>> 	  notifier = new Notifier(this);
>>       regionManager = new RegionManager(this);
>>    }
> 643c665,669
> <             if (channel != null)
> ---
>>             // We have to test both the channel and disp here, in
>>             // case we've passed in our own channel.  The dispatcher
>>             // must be created in either case.
>>             if ((channel != null) && (disp != null))
> 649,653c675,686
> <             // Try to create a multiplexer channel
> <             channel = getMultiplexerChannel();
> < 
> <             if (channel != null)
> <             {
> ---
>>             // Try to create a multiplexer channel if we didnt get a channel passed in
>>             if(isMyChannel){
>>             	channel = getMultiplexerChannel();
>>             }
>>             
>>             if ((channel != null) && isMyChannel)
>>             {
>>             	
>>                 // Success creating the multiplexer channel.
>>                 // Now we have to let the config know about our joy.
>>             	// Note that we never do this if we've passed in a channel,
>>             	// even if that channel is multiplexed.
> 676,680c709,712
> <                try
> <                {
> <                   channel = new JChannel(configuration.getClusterConfig());
> <                }
> <                catch (Exception e)
> ---
>>                
>>                // If we've not passed in a channel
>>                // we need to create a non-multiplexed one now
>>                if (isMyChannel) 
> 682,683c714,720
> <                   throw new CacheException("Unable to create JGroups channel", e);
> <                }
> ---
>> 					try {
>> 						channel = new JChannel(configuration.getClusterConfig());
>> 					} catch (Exception e) {
>> 						throw new CacheException(
>> 								"Unable to create JGroups channel", e);
>> 					}
>> 			   }
> Index: DefaultCacheFactory.java
> ===================================================================
> RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/DefaultCacheFactory.java,v
> retrieving revision 1.6
> diff -r1.6 DefaultCacheFactory.java
> 11a12
>> import org.jgroups.Channel;
> 102a104,135
>>    /**
>>     * This implementation clones the configuration passed in before using it.
>>     * It also allows the client to pass in its own channel.
>>     *
>>     * @param ch the pre-configured JChannel to use
>>     * @param configuration to use.  We assume that the channel has been setup using this
>>     * @param start         whether to start the cache
>>     * @return a cache
>>     * @throws ConfigurationException if there are problems with the cfg
>>     */
>>    public Cache<K, V> createCache(Channel ch, Configuration configuration, boolean start) throws ConfigurationException
>>    {
>>       try
>>       {
>>          CacheImpl<K, V> cache = new CacheImpl<K, V>(ch);
>>          cache.setConfiguration(configuration);
>>          if (start) cache.start();
>>          return cache;
>>       }
>>       catch (ConfigurationException ce)
>>       {
>>          throw ce;
>>       }
>>       catch (RuntimeException re)
>>       {
>>          throw re;
>>       }
>>       catch (Exception e)
>>       {
>>          throw new RuntimeException(e);
>>       }
>>    }


-- 
Brian Stansberry
Lead, AS Clustering
JBoss, a division of Red Hat
brian.stansberry at redhat.com




More information about the jbosscache-dev mailing list