groupmgmt.impl
Class SinglePhaseDisseminator

java.lang.Object
  extended bygroupmgmt.GroupDisseminator
      extended bygroupmgmt.impl.SinglePhaseDisseminator

public class SinglePhaseDisseminator
extends GroupDisseminator

The SinglePhaseDisseminator class. Responsible for coordinating group changes with members of the group.

This implementation does that via a "Single-phase transaction", ie it sends a message to everyone in the group and assumes that they got it. One member of the group is designated Leader, and it keeps a graph of the connections within its group (implemented as a Hashtable). The followers notify the leader of changes in their connections, and the leader updates its graph and changes the group when needed.

Multiple removes can be done simultaneously by the leader.
Adds must be serialized (to keep leader-leader communication simple), this is done by the ConnectionChangeQueue.

Messages used:

## FUTURE WORK:
##
## anticipate potential problems with refusedchanges.
## (theoretically ConnectionChangeMessages could get out of order).
## handle unexpected loss of connection to leader/robustness in general
## test with large groups. algorithms fast/scalable enough?

Version:
July 2003
Author:
Christine Julien, Tom Elgin

Nested Class Summary
private  class SinglePhaseDisseminator.ConnectionChangeQueue
          Private inner class to maintain a queue of connection changes to be processed.
private  class SinglePhaseDisseminator.DebugFrame
          ## For testing.
private  class SinglePhaseDisseminator.MessageListener
          A private inner class to listen for group changes (non-leaders) or notification messages (leaders).
private  class SinglePhaseDisseminator.ProcessMessageQueue
          Queue so that we can pause processing of messages during disengagement.
 
Field Summary
private  SinglePhaseDisseminator.ConnectionChangeQueue connectionChangeQueue
          Leader-only.
private  java.util.Hashtable connections
          Leader-only.
private  SinglePhaseDisseminator.DebugFrame debugFrame
          For debugging.
private  boolean debugging
          Determines whether to output log messages and show debugFrame.
private  java.lang.Boolean disengaging
          If I am currently disengaging, is set to true.
private  int disseminatorPort
          The port to send/receive messages on.
private  Member engaging
          If I am currently engaging, contains the Member with which I'm engaging.
private  SPGroupChangeMessage lastGroupChangeMessage
          Keep track of the last GroupChangeMessage we've received in order to make sure new ones are in fact newer.
private  Member leader
          Reference to the leader of the group.
private  SinglePhaseDisseminator.MessageListener messageListener
          Listens for messages from fellow group members.
private  int portOffset
          The offset to use to find the port that the disseminators should communicate on (relative to the groupmgmt port passed to GroupManager).
private  SinglePhaseDisseminator.ProcessMessageQueue processMessageQueue
          Queues received messages for processing.
 
Fields inherited from class groupmgmt.GroupDisseminator
 
Constructor Summary
SinglePhaseDisseminator(int portOffset)
          Constructor.
 
Method Summary
private  void addConnection(Member m1, Member m2)
          Private utility method to add a connection to my network graph.
 void changeGroup(Member[] arriving, Member[] departing)
          Process a change in connectivity detected by MemberDetector Send it to the connectionChangeQueue to process.
protected  void fireGroupChangedEvent(java.util.Vector members)
          Helper method to automatically construct the event before firing.
private  void getGroupOfMember(Member m, java.util.Vector g, java.util.Hashtable table, java.util.Hashtable newTable)
          Leader-only.
private  boolean isLeader()
          Accessor to isLeader variable.
private  void log(java.lang.String msg)
          For testing.
private  java.util.Vector partitionGroups()
          Leader-only.
private  void processArriving(SPChange arrive)
          Leader-only.
private  void processChangeRefusedMessage(SPChangeRefusedMessage message)
          The connection change we sent to a leader has been refused because it no longer applies to that leader.
private  void processConnectionChangesMessage(SPConnectionChangesMessage m)
          Leader-only.
private  void processDeparting(java.util.Vector departing)
          Leader-only.
private  void processGetLeaderMessage(SPGetLeaderMessage message)
          Sent by the leader of another group that wishes to add me.
private  void processGroupChangeMessage(SPGroupChangeMessage message)
          Process a change in the group (split or new members) sent out by the leader.
private  void processGroupInfoMessage(SPGroupInfoMessage message)
          Leader-only.
private  void processLeaderAddressMessage(SPLeaderAddressMessage message)
          Leader-only.
private  void processMessage(java.lang.Object message)
          Process a Message received by the MessageListener.
private  void sendMessage(Member receiver, java.io.Serializable message)
          Utility method to send a message to a Member.
private  void sendMessage(java.util.Vector receivers, java.io.Serializable message)
           
private  void sendOutGroup(java.util.Hashtable gconns, Member gleader, java.util.Vector gmembers)
          Utility method to send GroupChangeMessages creating a new group.
 void setDebug(boolean debugging)
          Determine whether to output logging messages.
protected  void start()
          Start responding to changeGroup messages.
protected  void stop()
          Suspend all activity - stop responding to changeGroup events.
 
Methods inherited from class groupmgmt.GroupDisseminator
addGroupChangedListener, fireGroupChangedEvent, isActive, removeGroupChangedListener
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

disseminatorPort

private int disseminatorPort
The port to send/receive messages on. Set by adding portOffset to the port passed to GroupManager. Note that if the port is in use, we exit.


portOffset

private int portOffset
The offset to use to find the port that the disseminators should communicate on (relative to the groupmgmt port passed to GroupManager).


messageListener

private SinglePhaseDisseminator.MessageListener messageListener
Listens for messages from fellow group members.


connectionChangeQueue

private SinglePhaseDisseminator.ConnectionChangeQueue connectionChangeQueue
Leader-only. Queues ConnectionChanges to be processed.


processMessageQueue

private SinglePhaseDisseminator.ProcessMessageQueue processMessageQueue
Queues received messages for processing.


leader

private Member leader
Reference to the leader of the group.


connections

private java.util.Hashtable connections
Leader-only. A Hashtable, keyed by Member, with each element being a Vector of other Members that the Member has a connection to. Connections are not assumed or guaranteed to be symmetric here, but they should end up being symmetric.


engaging

private Member engaging
If I am currently engaging, contains the Member with which I'm engaging. For synchronization purposes - allows us to block while engaging with a Member.


disengaging

private java.lang.Boolean disengaging
If I am currently disengaging, is set to true. For synchronization purposes - allows us to block while splitting the group.


lastGroupChangeMessage

private SPGroupChangeMessage lastGroupChangeMessage
Keep track of the last GroupChangeMessage we've received in order to make sure new ones are in fact newer.


debugFrame

private SinglePhaseDisseminator.DebugFrame debugFrame
For debugging.


debugging

private boolean debugging
Determines whether to output log messages and show debugFrame.

Constructor Detail

SinglePhaseDisseminator

public SinglePhaseDisseminator(int portOffset)
Constructor. Sets port offset and calls super().

Parameters:
portOffset - The offset (relative to the groupmgmt port) to use when communicating with another member's disseminator.
Method Detail

setDebug

public void setDebug(boolean debugging)
Determine whether to output logging messages.

Parameters:
debugging - Outputs messages if true.

start

protected void start()
Start responding to changeGroup messages. (May also start listening for network messages from members)

Specified by:
start in class GroupDisseminator

stop

protected void stop()
Suspend all activity - stop responding to changeGroup events.

Specified by:
stop in class GroupDisseminator

isLeader

private boolean isLeader()
Accessor to isLeader variable.

Returns:
True if I'm the group leader, false otherwise.

changeGroup

public void changeGroup(Member[] arriving,
                        Member[] departing)
Process a change in connectivity detected by MemberDetector Send it to the connectionChangeQueue to process.

Specified by:
changeGroup in class GroupDisseminator
Parameters:
arriving - The new Member(s).
departing - The leaving Member(s).

processConnectionChangesMessage

private void processConnectionChangesMessage(SPConnectionChangesMessage m)
Leader-only. Update the connections Hashtable to reflect changes in Member connectivity. If there are new Member(s) or any old Member(s) have been disconnected from the group, then do a group change.


processChangeRefusedMessage

private void processChangeRefusedMessage(SPChangeRefusedMessage message)
The connection change we sent to a leader has been refused because it no longer applies to that leader. Stick it in the queue again to be sent to the new leader (could be myself).


processArriving

private void processArriving(SPChange arrive)
Leader-only. Add a new Member. First step is to ask the new member for it's leader's address. They will send back a LeaderAddressMessage and then if that leader should lead the new group we'll send a GroupInfoMessage. If we should lead the new group we wait and assume they will send us a GetLeaderMessage, to which we will reply with a LeaderAddressMessage, and they'll reply with a GroupInfoMessage. Then we'll lead the new group.

Parameters:
arrive - The connection to add.

processDeparting

private void processDeparting(java.util.Vector departing)
Leader-only. Changes the connections table to reflect newly dropped connections. Then checks to see if group needs to be split, and if so sends out GroupChangeMessages.

Parameters:
departing - A Vector containing SPChange objects for all of the dropped connections to process. This method removes the SPChange objects that it processes from departing.

partitionGroups

private java.util.Vector partitionGroups()
Leader-only. Helper method for processDeparting() to determine who's connected to whom, and who should lead the new group(s).

Returns:
Vector of groups. Each group is a vector, with its connections as the first element, its leader as the second, and then the rest of the Members.

getGroupOfMember

private void getGroupOfMember(Member m,
                              java.util.Vector g,
                              java.util.Hashtable table,
                              java.util.Hashtable newTable)
Leader-only. Recursive helper method for partitionGroups() to construct a group and connections table from everyone connected to Member m. Removes connections for this group from the initial connections table.

Parameters:
m - The Member to start the new group with.
g - The group.
table - The initial connections hashtable.
newTable - Hashtable to fill with the connections for this group.

processLeaderAddressMessage

private void processLeaderAddressMessage(SPLeaderAddressMessage message)
Leader-only. We got the newMember's Leader's address, now check if it's higher than my address, and if so send a GroupInfoMessage. Otherwise we wait for a GroupInfoMessage from the other leader. This works because connections are assumed to be symmetric.


processGroupInfoMessage

private void processGroupInfoMessage(SPGroupInfoMessage message)
Leader-only. Process a GroupInfoMessage from another leader. Merge it's connections with mine and then send GroupChangeMessages to everyone indicating the new, merged group. (I remain leader).


processGetLeaderMessage

private void processGetLeaderMessage(SPGetLeaderMessage message)
Sent by the leader of another group that wishes to add me. Respond by telling them my leader's address.


processGroupChangeMessage

private void processGroupChangeMessage(SPGroupChangeMessage message)
Process a change in the group (split or new members) sent out by the leader. Tells all about my new group - the leader, the members, and if I'm the leader it tells me the connections too.

Parameters:
message - The GroupChangeMessage.

addConnection

private void addConnection(Member m1,
                           Member m2)
Private utility method to add a connection to my network graph. Connections are symmetric.

Parameters:
m1 - A Member.
m2 - The Member connected to m1.

sendOutGroup

private void sendOutGroup(java.util.Hashtable gconns,
                          Member gleader,
                          java.util.Vector gmembers)
Utility method to send GroupChangeMessages creating a new group.

Parameters:
gconns - The connections table for the new group.
gleader - The leader of the new group.
gmembers - The members of the new group (including the leader).

sendMessage

private void sendMessage(Member receiver,
                         java.io.Serializable message)
Utility method to send a message to a Member.

Parameters:
receiver - The Member to send the message to.
message - The message to send.

sendMessage

private void sendMessage(java.util.Vector receivers,
                         java.io.Serializable message)

processMessage

private void processMessage(java.lang.Object message)
Process a Message received by the MessageListener.

Parameters:
message - The Message to process.

fireGroupChangedEvent

protected void fireGroupChangedEvent(java.util.Vector members)
Helper method to automatically construct the event before firing.


log

private void log(java.lang.String msg)
For testing. Output a message to the command line.