next up previous contents
Next: Disconnecting from a channel Up: Channel Previous: Peeking at a message   Contents


Getting the group's state

A newly joined member may wish to retrieve the state of the group before starting work. This is done calling either getState() of getStates(). The first method returns the state of one member (in most cases, of the oldest member, the coordinator) whereas the latter returns the states of all members. This method returns true or false, depending on whether a valid state could be retrieved. For example, if a member is a singleton, then calling this method would always return false3.5.

The actual state is returned as the return value of one of the subsequent receive() calls, in the form of a SetStateEvent object. If getState(s) returned true, then a valid state (non-null) will be returned, otherwise a null state will be returned. Alternatively if an application uses MembershipListener (see 3.2.3) instead of pulling messages from a channel, the getState() method will be invoked and a copy of the current state should be returned. By the same token, setting a state would be accomplished by JavaGroups calling the setState() method of the state fetcher.

The reason for not directly returning the state as a result of getState() is that the state has to be returned in the correct position relative to other messages. Returning it directly would violate the FIFO properties of a channel, and state transfer would not be correct.

The following code fragment shows how a group member participates in state transfers:

    channel=new JChannel("UDP:PING:FD:GMS:STATE_TRANSFER:QUEUE");
    channel.setOpt(Channel.GET_STATE_EVENTS, new Boolean(true));
    channel.connect("TestChannel");
    boolean rc=channel.getState(5000);

    ...

    Object state, copy;
    Object ret=channel.receive(0);
    if(ret instanceof Message)
        ;
    else if(ret instanceof GetStateEvent) {
        copy=copyState(state); // make a copy so that other msgs don't change the state
        channel.returnState(Util.objectToByteBuffer(copy));
    }
    else if(ret instanceof SetStateEvent) {
        SetStateEvent e=(SetStateEvent)ret;
        // set state from ret.GetArg();
    }

A JChannel has to be created whose stack includes the STATE_TRANSFER or pbcast.STATE_TRANSFER protocols (see 5). Option GET_STATE_EVENTS should be enabled, as the channel might probably want to return its current state if asked. Method getState() subsequently asks the channel to return the current state. If there is a current state (there may not be any other members in the group !), then true is returned. In this case, one of the subsequent receive() method invocations on the channel will return a SetStateEvent object which contains the current state. In this case, the caller sets its state to the one received from the channel.

If state transfer events are enabled, then receive() might return a GetStateEvent object, requesting the state of the member to be returned. In this case, a copy of the current state should be made and returned using JChannel.returnState(). It is important to a) synchronize access to the state when returning it since other accesses may modify it while it is being returned and b) make a copy of the state since other accesses after returning the state may still be able to modify it ! This is possible because the state is not immediately returned, but travels down the stack (in the same address space), and a reference to it could still alter it.

The details of state transfer as implemented in JavaGroups are discussed in the Programmer's Guide.


next up previous contents
Next: Disconnecting from a channel Up: Channel Previous: Peeking at a message   Contents
Bela Ban 2002-11-16