[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