8 Replies Latest reply on Nov 9, 2006 6:57 AM by manik

    Partial state transfer -when target root integration is not

    vblagojevic

      Hi,

      While converting partial state transfer from RPC based mechanism I realized that there are numerous cases when partial state requested from target cache subroot is not integrated at recipient cache at the same subroot. This is particularly case with buddy backup manager.

      As you might be aware I am trying to migrate partial state transfer to Jgroups callbacks. However, the problem is that jgroups partial state transfer does not accommodate this idea out-of-the box. Once channel1 requests partial state with channel1.getState(String state_id) it eventually receives setState callback with the same state_id. This callback is the handed of to StateTransferManager with that state_id.

      In order to accomodate integration under a different subroot I will encode state_id from getState call with a special delimeter between the requested fqn subtree and target fqn subtree. Therefore,

      ch.getState("/a/b$INTEGRATION_TARGET$/c",timeout);

      would mean fetch state from /a/b but integrate it under /c.

      Of course this will all be hidden by higher level API and in TreeCache.MessageListeberAdaptor that would strip this delimeter out.

      If you have an advice or a comment - speak up.

      Regards,
      Vladimir

        • 1. Re: Partial state transfer -when target root integration is
          genman

          What if b is not a string FQN? I guess that's not likely, but just a thought.

          • 2. Re: Partial state transfer -when target root integration is
            vblagojevic

            That is a good point. I think although we have designed FQN class to allow non string fqns so much JBC code relies on the fact that fqns are strings. We should be clear about the fact that only string fqns are acceptable. Manik?



            • 3. Re: Partial state transfer -when target root integration is
              vblagojevic
              • 4. Re: Partial state transfer -when target root integration is
                manik

                 


                Brian has answered this question http://jboss.org/index.html?module=bb&op=viewtopic&t=94157


                That is just regarding JGroups' requirement of String based FQNs for SST.

                The other issue here is how we'd deal with partial state to a different subtree, why do we need the integration point to be specified using a delim?

                When the channel calls setState(), does the implementing code have access of the sender? If so, in the case of BR, can't the subtree to attach this state be calculated?



                • 5. Re: Partial state transfer -when target root integration is
                  vblagojevic

                  We need delim because in JGroups once channel1 requests partial state with channel1.getState(String state_id) it eventually receives setState callback with the *same state_id*. This is a problem for partial state transfer that has to be integrated in a different subroot that source subroot.

                  I am not sure I understand your question regarding BR. I've seen BR code and it transfers state in a map through RPC call. Maybe we have to convert this somehow to make use of partial state transfer.

                  I am providing code, still local on my laptop, that explains how this encoding is done. I think code will be more clear than my English :)

                  TreeCache.MessageListenerAdaptor.getState

                  public byte[] getState(String state_id)
                   {
                   String sourceRoot = state_id;
                   boolean hasDifferentSourceAndIntegrationRoots = state_id.indexOf(StateTransferManager.PARTIAL_STATE_DELIMETER)>0;
                   if(hasDifferentSourceAndIntegrationRoots)
                   {
                   sourceRoot = state_id.split(StateTransferManager.PARTIAL_STATE_DELIMETER)[0];
                   }
                   try
                   {
                   return _getState(Fqn.fromString(sourceRoot), timeout, true, true);
                   }
                   catch (Throwable t)
                   {
                   my_log.error("Caught " + t.getClass().getName() +
                   " while responding to partial state transfer request;" +
                   " returning null", t);
                   return null;
                   }
                   }



                  TreeCache.MessageListenerAdaptor.setState
                  public void setState(String state_id, byte[] state)
                   {
                   String targetRoot = state_id;
                   boolean hasDifferentSourceAndIntegrationRoots = state_id.indexOf(StateTransferManager.PARTIAL_STATE_DELIMETER)>0;
                   if(hasDifferentSourceAndIntegrationRoots)
                   {
                   targetRoot = state_id.split(StateTransferManager.PARTIAL_STATE_DELIMETER)[1];
                   }
                   try
                   {
                  
                   if (state != null)
                   {
                   my_log.debug("Setting received partial state for subroot " +state_id);
                   Fqn subroot = Fqn.fromString(targetRoot);
                   Region region = regionManager.getRegion(subroot,false);
                   ClassLoader cl = null;
                   if(region!= null)
                   {
                   // If a classloader is registered for the node's region, use it
                   cl = region.getClassLoader();
                   }
                   getStateTransferManager().setState(state, subroot, cl);
                   isStateSet = true;
                   }
                   }
                  ....
                  ...
                  }


                  TreeCache.fetchPartialState()
                  public void fetchPartialState(Object sources [], Fqn sourceTarget, Fqn integrationTarget) throws Exception
                   {
                   String encodedStateId = sourceTarget + StateTransferManager.PARTIAL_STATE_DELIMETER + integrationTarget;
                   fetchPartialState(sources,encodedStateId);
                   }
                  


                  • 6. Re: Partial state transfer -when target root integration is
                    manik

                    Yeah, I guess that works since the actual delimiter stuff is internal to the STM and the Listener. The rest of the codebase deals with srcs and targets.

                    Forget what I said earlier - it is very hacky and relies on how BR backup Fqns are built.

                    • 7. Re: Partial state transfer -when target root integration is
                      brian.stansberry

                       

                      "manik.surtani@jboss.com" wrote:

                      Forget what I said earlier - it is very hacky and relies on how BR backup Fqns are built.


                      Why is that hacky? IIRC, if the cache is configured for BR, *any* state transfer follows this pattern (please double check if I'm wrong):

                      1) Node that prepares state gets it from the main tree.
                      2) Node the receives state integrates it into a buddy backup subtree.

                      If this is the case, the rules for determining whether Fqn translation needs to be done are clear, and can be encapsulated in the StateTransferManager. The rules for translating the Fqns are clear and the Fqn translation operation can be encapsulated in the BuddyManager. I don't see any reason the translation needs to be embedded in the JGroups string.

                      Don't get me wrong; I'm not strongly opposed to embedding it; it's just that I don't think it's required, and can be avoided if there's concern it will prove to be a problem down the road.

                      • 8. Re: Partial state transfer -when target root integration is
                        manik

                         


                        Why is that hacky? IIRC, if the cache is configured for BR, *any* state transfer follows this pattern (please double check if I'm wrong):


                        Because you only solve the problem for BR, not for a generic mechanism for being able to integrate state to a different subtree. No specific use now, but may be handy later.