public virtual void castViewChange(View new_view, Digest digest) { Message view_change_msg; HDR hdr; Stack.NCacheLog.Debug("pb.GMS.castViewChange()", "mcasting view {" + new_view + "} (" + new_view.size() + " mbrs)\n"); if (new_view != null) new_view.BridgeSourceCacheId = impl.UniqueId; view_change_msg = new Message(); // bcast to all members hdr = new HDR(HDR.VIEW, new_view); hdr.digest = digest; view_change_msg.putHeader(HeaderType.GMS, hdr); view_change_msg.Dests = new_view.Members.Clone() as ArrayList; if(stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("CastView.Watch", "Count of members: " + new_view.Members.Count.ToString()); //TODO: we need to handle scenario when we dont recive castView change from a node _promise = new ViewPromise(new_view.Members.Count); bool waitForViewAcknowledgement = true ; if (!new_view.containsMember(local_addr)) //i am leaving { waitForViewAcknowledgement = false; if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("GMS.castViewChange()", "I am coordinator and i am leaving"); passDown(new Event(Event.MSG, view_change_msg, Priority.Critical)); } else passDown(new Event(Event.MSG, view_change_msg, Priority.Critical)); if (waitForViewAcknowledgement) { _promise.WaitResult(_castViewChangeTimeOut); if (!_promise.AllResultsReceived()) //retry { view_change_msg.Dests = new_view.Members.Clone() as ArrayList; passDown(new Event(Event.MSG, view_change_msg, Priority.Critical)); _promise.WaitResult(_castViewChangeTimeOut); } if (_promise.AllResultsReceived()) { Stack.NCacheLog.CriticalInfo("GMS.castViewChange()", "View applied"); } } }
public abstract void handleViewChange(View new_view, Digest digest);
public static View ReadView(CompactReader reader) { byte isNull = reader.ReadByte(); if (isNull == 1) return null; View newView = new View(); newView.Deserialize(reader); return newView; }
/// <summary> If we are leaving, we have to wait for the view change (last msg in the current view) that /// excludes us before we can leave. /// </summary> /// <param name="new_view">The view to be installed /// </param> /// <param name="digest"> If view is a MergeView, digest contains the seqno digest of all members and has to /// be set by GMS /// </param> public override void handleViewChange(View new_view, Digest digest) { if (gms.Stack.NCacheLog.IsInfoEnabled) gms.Stack.NCacheLog.Info("ParticipentGMSImpl.handleViewChange", "received view"); System.Collections.ArrayList mbrs = new_view.Members; gms.Stack.NCacheLog.Debug("view=");// + new_view); suspected_mbrs.Clear(); if (leaving && !mbrs.Contains(gms.local_addr)) { // received a view in which I'm not member: ignore return ; } ViewId vid = gms.view_id != null ? gms.view_id.Copy() : null; if (vid != null) { int rc = vid.CompareTo(new_view.Vid); if (rc < 0) { isNewMember = false; if (gms.Stack.NCacheLog.IsInfoEnabled) gms.Stack.NCacheLog.Info("ParticipantGmsImp", "isNewMember : " + isNewMember); } } gms.installView(new_view, digest); }
private bool installView(View new_view) { ArrayList mems = new_view.Members; gms.Stack.NCacheLog.Debug("pb.ClientGmsImpl.installView()", "new_view=" + new_view); if (gms.local_addr == null || mems == null || !mems.Contains(gms.local_addr)) { gms.Stack.NCacheLog.Error("pb.ClientGmsImpl.installView()", "I (" + gms.local_addr + ") am not member of " + Global.CollectionToString(mems) + ", will not install view"); return false; } Address replica = (Address)gms.members.Members[1]; //Cast view to the replica node as well gms.installView(new_view); gms.becomeParticipant(); gms.Stack.IsOperational = true; return true; }
/// <summary> Send back a response containing view and digest to sender</summary> internal virtual void sendMergeResponse(Address sender, View view, Digest digest) { Message msg = new Message(sender, null, null); GMS.HDR hdr = new GMS.HDR(GMS.HDR.MERGE_RSP); hdr.merge_id = merge_id; hdr.view = view; hdr.digest = digest; msg.putHeader(HeaderType.GMS, hdr); gms.Stack.NCacheLog.Debug("response=" + hdr); gms.passDown(new Event(Event.MSG, msg)); }
internal virtual void becomeSingletonMember(Address mbr) { Digest initial_digest; ViewId view_id = null; ArrayList mbrs = ArrayList.Synchronized(new ArrayList(1)); // set the initial digest (since I'm the first member) initial_digest = new Digest(1); // 1 member (it's only me) initial_digest.add(gms.local_addr, 0, 0); // initial seqno mcast by me will be 1 (highest seen +1) gms.Digest = initial_digest; view_id = new ViewId(mbr); // create singleton view with mbr as only member mbrs.Add(mbr); View v = new View(view_id, mbrs); v.CoordinatorGmsId = gms.unique_id; ArrayList subgroupMbrs = new ArrayList(); subgroupMbrs.Add(mbr); gms._subGroupMbrsMap[gms.subGroup_addr] = subgroupMbrs; gms._mbrSubGroupMap[mbr] = gms.subGroup_addr; v.SequencerTbl = gms._subGroupMbrsMap.Clone() as Hashtable; v.MbrsSubgroupMap = gms._mbrSubGroupMap.Clone() as Hashtable; v.AddGmsId(mbr, gms.unique_id); gms.installView(v); gms.becomeCoordinator(); // not really necessary - installView() should do it gms.Stack.IsOperational = true; gms.Stack.NCacheLog.Debug("pb.ClientGmsImpl.becomeSingletonMember()", "created group (first member). My view is " + gms.view_id + ", impl is " + gms.Impl.GetType().FullName); }
/// <summary> Connects the channel to a group.<BR> /// If the channel is already connected, an error message will be printed to the error log<BR> /// If the channel is closed a ChannelClosed exception will be thrown<BR> /// This method starts the protocol stack by calling ProtocolStack.start<BR> /// then it sends an Event.CONNECT event down the stack and waits to receive a CONNECT_OK event<BR> /// Once the CONNECT_OK event arrives from the protocol stack, any channel listeners are notified<BR> /// and the channel is considered connected<BR> /// /// </summary> /// <param name="channel_name">A <code>String</code> denoting the group name. Cannot be null. /// </param> /// <exception cref=""> ChannelException The protocol stack cannot be started /// </exception> /// <exception cref=""> ChannelClosedException The channel is closed and therefore cannot be used any longer. /// A new channel has to be created first. /// </exception> public override void connect(string channel_name, string subGroup_name, bool isStartedAsMirror,bool twoPhaseInitialization) { lock (this) { /*make sure the channel is not closed*/ checkClosed(); _isStartedAsMirror = isStartedAsMirror; /*if we already are connected, then ignore this*/ if (connected) { NCacheLog.Error("GroupChannel", "already connected to " + channel_name); return ; } /*make sure we have a valid channel name*/ if (channel_name == null) { NCacheLog.Error("GroupChannel", "channel_name is null, assuming unicast channel"); } else this.channel_name = channel_name; //============================================= if (subGroup_name != null) this.subGroup_name = subGroup_name; //============================================= try { prot_stack.startStack(); // calls start() in all protocols, from top to bottom } catch (System.Exception e) { NCacheLog.Error("GroupChannel.connect()", "exception: " + e); throw new ChannelException(e.Message,e); } /* try to get LOCAL_ADDR_TIMEOUT. Catch Exception thrown if called * in an untrusted environment (e.g. using JNLP) */ LOCAL_ADDR_TIMEOUT = 30000; /* Wait LOCAL_ADDR_TIMEOUT milliseconds for local_addr to have a non-null value (set by SET_LOCAL_ADDRESS) */ lock (local_addr_mutex) { long wait_time = LOCAL_ADDR_TIMEOUT, start = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; while (local_addr == null && wait_time > 0) { try { System.Threading.Monitor.Wait(local_addr_mutex, TimeSpan.FromMilliseconds(wait_time)); } catch (System.Threading.ThreadInterruptedException e) { NCacheLog.Error("GroupChannel.connect():2", "exception=" + e); } wait_time -= ((System.DateTime.Now.Ticks - 621355968000000000) / 10000 - start); } if (wait_time < 0) { NCacheLog.Fatal( "[Timeout]GroupChannel.connect:" + wait_time); } } // ProtocolStack.start() must have given us a valid local address; if not we won't be able to continue if (local_addr == null) { NCacheLog.Error("GroupChannel", "local_addr == null; cannot connect"); throw new ChannelException("local_addr is null"); } /*create a temporary view, assume this channel is the only member and *is the coordinator*/ System.Collections.ArrayList t = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(1)); t.Add(local_addr); my_view = new View(local_addr, 0, t); // create a dummy view // only connect if we are not a unicast channel if (channel_name != null) { /* Wait for notification that the channel has been connected to the group */ lock (connect_mutex) { // wait for CONNECT_OK event Event connect_event = new Event(Event.CONNECT, new object[] { channel_name, subGroup_name, isStartedAsMirror,twoPhaseInitialization }); connect_ok_event_received = false; // added patch by Roland Kurman (see history.txt) down(connect_event); try { while (!connect_ok_event_received) System.Threading.Monitor.Wait(connect_mutex); } catch (System.Exception e) { NCacheLog.Error("GroupChannel.connect():2", "exception=" + e); } } } /*notify any channel listeners*/ connected = true; if (channel_listener != null) channel_listener.channelConnected(this); } }
/// <summary> Callback method <BR> /// Called by the ProtocolStack when a message is received. /// It will be added to the message queue from which subsequent /// <code>Receive</code>s will dequeue it. /// </summary> /// <param name="evt">the event carrying the message from the protocol stack /// </param> public virtual void up(Event evt) { int type = evt.Type; Message msg; /*if the queue is not available, there is no point in *processing the message at all*/ if (mq == null) { NCacheLog.Error("GroupChannel.up", "message queue is null."); return ; } switch (type) { case Event.MSG: msg = (Message) evt.Arg; if (!receive_local_msgs) { if (local_addr != null && msg.Src != null) if (local_addr.Equals(msg.Src)) return ; } break; case Event.VIEW_CHANGE: my_view = (View) evt.Arg; // crude solution to bug #775120: if we get our first view *before* the CONNECT_OK, // we simply set the state to connected if (connected == false) { connected = true; lock (connect_mutex) { // bug fix contributed by Chris Wampler (bug #943881) connect_ok_event_received = true; System.Threading.Monitor.Pulse(connect_mutex); } } // unblock queueing of messages due to previous BLOCK event: down(new Event(Event.STOP_QUEUEING)); if (!receive_views) // discard if client has not set receving views to on return ; break; case Event.SUSPECT: if (!receive_suspects) return ; break; case Event.CONFIG: System.Collections.Hashtable config = (System.Collections.Hashtable) evt.Arg; break; case Event.BLOCK: // If BLOCK is received by application, then we trust the application to not send // any more messages until a VIEW_CHANGE is received. Otherwise (BLOCKs are disabled), // we queue any messages sent until the next VIEW_CHANGE (they will be sent in the // next view) if (!receive_blocks) { // discard if client has not set 'receiving blocks' to 'on' down(new Event(Event.BLOCK_OK)); down(new Event(Event.START_QUEUEING)); return ; } break; case Event.CONNECT_OK: lock (connect_mutex) { connect_ok_event_received = true; System.Threading.Monitor.Pulse(connect_mutex); } break; case Event.CONNECT_OK_PHASE_2: lock (connect_mutex_phase2) { connect_ok_event_received_phase2 = true; System.Threading.Monitor.Pulse(connect_mutex_phase2); } break; case Event.DISCONNECT_OK: lock (disconnect_mutex) { disconnect_ok_event_received = true; System.Threading.Monitor.PulseAll(disconnect_mutex); } break; case Event.SET_LOCAL_ADDRESS: lock (local_addr_mutex) { local_addr = (Address) evt.Arg; System.Threading.Monitor.PulseAll(local_addr_mutex); } break; case Event.EXIT: handleExit(evt); return ; // no need to pass event up; already done in handleExit() case Event.BLOCK_SEND: lock (flow_control_mutex) { NCacheLog.Error("GroupChannel.up", "received BLOCK_SEND."); block_sending = true; System.Threading.Monitor.PulseAll(flow_control_mutex); } break; case Event.UNBLOCK_SEND: lock (flow_control_mutex) { NCacheLog.Error("GroupChannel.up", "received UNBLOCK_SEND."); block_sending = false; System.Threading.Monitor.PulseAll(flow_control_mutex); } break; default: break; } // If UpHandler is installed, pass all events to it and return (UpHandler is e.g. a building block) if (up_handler != null) { up_handler.up(evt); return ; } if (type == Event.MSG || type == Event.VIEW_CHANGE || type == Event.SUSPECT /*|| type == Event.GET_APPLSTATE*/ || type == Event.BLOCK) { try { mq.add(evt); } catch (System.Exception e) { NCacheLog.Error("GroupChannel.up()", e.ToString()); } } }
/// <summary> Any member of 'membership' that is not in the new view is flagged as /// SUSPECTED. Any member in the new view that is <em>not</em> in the /// membership (ie, the set of responses expected for the current RPC) will /// <em>not</em> be added to it. If we did this we might run into the /// following problem: /// <ul> /// <li>Membership is {A,B} /// <li>A sends a synchronous group RPC (which sleeps for 60 secs in the /// invocation handler) /// <li>C joins while A waits for responses from A and B /// <li>If this would generate a new view {A,B,C} and if this expanded the /// response set to {A,B,C}, A would wait forever on C's response because C /// never received the request in the first place, therefore won't send a /// response. /// </ul> /// </summary> public virtual void viewChange(View new_view) { Address mbr; ArrayList mbrs = new_view != null ? new_view.Members : null; if (membership == null || membership.Length == 0 || mbrs == null) return; lock (rsp_mutex) { ArrayList oldMembership = clusterMembership != null ? clusterMembership.Clone() as ArrayList : null; clusterMembership.Clear(); clusterMembership.AddRange(mbrs); this.members.Clear(); this.members.AddRange(mbrs); for (int i = 0; i < membership.Length; i++) { mbr = membership[i]; if (!mbrs.Contains(mbr)) { addSuspect(mbr); responses[i] = null; received[i] = SUSPECTED; } if (oldMembership != null) oldMembership.Remove(mbr); } //by this time, membershipClone cotains all those members that are not part of //group request normal membership and are no longer part of the cluster membership //according to the new view. //this way we are suspecting replica members. if (oldMembership != null) { foreach (Address member in oldMembership) { if (!mbrs.Contains(member)) receivedFromNHops[member] = SUSPECTED; } } System.Threading.Monitor.PulseAll(rsp_mutex); } }
/* ----------------------------------- Private Methods ------------------------------------- */ /// <summary> Initializes all variables. Used after <tt>close()</tt> or <tt>disconnect()</tt>, /// to be ready for new <tt>connect()</tt> /// </summary> private void init() { local_addr = null; channel_name = null; my_view = null; connect_ok_event_received = false; disconnect_ok_event_received = false; connected = false; block_sending = false; }
public virtual View makeView(System.Collections.ArrayList mbrs, ViewId vid) { Address coord = null; long id = 0; if (vid != null) { coord = vid.CoordAddress; id = vid.Id; } View view = new View(coord, id, mbrs); view.CoordinatorGmsId = unique_id; return view; }
/// <summary> Sets the new view and sends a VIEW_CHANGE event up and down the stack.</summary> public virtual void installView(View new_view) { Stack.NCacheLog.CriticalInfo("GMS.InstallView", "Installing new View " + local_addr.ToString() + " --> " + new_view); Address coord = null; try { //Lest inform coordinator about view receiption SendViewAcknowledgment(new_view.Coordinator); int rc; ViewId vid = new_view.Vid; System.Collections.ArrayList mbrs = new_view.Members; impl.UniqueId = new_view.BridgeSourceCacheId; _uniqueID = new_view.BridgeSourceCacheId; if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("[local_addr=" + local_addr + "] view is " + new_view); // Discards view with id lower than our own. Will be installed without check if first view if (view_id != null) { rc = vid.CompareTo(view_id); if (rc <= 0) { Stack.NCacheLog.Error("[" + local_addr + "] received view <= current view;" + " discarding it (current vid: " + view_id + ", new vid: " + vid + ')'); Event viewEvt = new Event(Event.VIEW_CHANGE_OK, null, Priority.Critical); passDown(viewEvt); return; } Address currentCoodinator = determineCoordinator(); Address newCoordinator = new_view.Coordinator; Address sender = vid.CoordAddress; // creater of the view if (!currentCoodinator.Equals(newCoordinator) && !newCoordinator.Equals(local_addr) && !sender.Equals(currentCoodinator)) { Stack.NCacheLog.CriticalInfo("GMS.InstallView", "Force Join Cluster"); if (!new_view.ForceInstall) { if (!VerifySuspect(currentCoodinator)) { Stack.NCacheLog.Error("GMS.installView", "rejecting the view from " + newCoordinator + " as my own coordinator[" + currentCoodinator + "] is not down"); Event viewEvt = new Event(Event.VIEW_CHANGE_OK, null, Priority.Critical); passDown(viewEvt); //we should inform the coordinator of this view that i can't be the member //of your view as my own coordinator is alive. Message msg = new Message(new_view.Coordinator, null, new byte[0]); msg.putHeader(HeaderType.GMS, new GMS.HDR(GMS.HDR.VIEW_REJECTED, local_addr)); passDown(new Event(Event.MSG, msg, Priority.Critical)); return; } } } } ltime = System.Math.Max(vid.Id, ltime); // compute Lamport logical time /* Check for self-inclusion: if I'm not part of the new membership, I just discard it. This ensures that messages sent in view V1 are only received by members of V1 */ if (checkSelfInclusion(mbrs) == false) { Stack.NCacheLog.Error("GMS.InstallView", "CheckSelfInclusion() failed, " + local_addr + " is not a member of view " + new_view + "; discarding view"); // only shun if this member was previously part of the group. avoids problem where multiple // members (e.g. X,Y,Z) join {A,B} concurrently, X is joined first, and Y and Z get view // {A,B,X}, which would cause Y and Z to be shunned as they are not part of the membership // bela Nov 20 2003 if (shun && local_addr != null && prev_members.contains(local_addr)) { Stack.NCacheLog.CriticalInfo("I (" + local_addr + ") am being shunned, will leave and " + "rejoin group (prev_members are " + prev_members + ')'); passUp(new Event(Event.EXIT)); } return; } lock (members) { //@UH Members are same as in the previous view. No need to apply view if (view_id != null) { Membership newMembers = new Membership(mbrs); if (members.Equals(newMembers) && vid.CoordAddress.Equals(view_id.CoordAddress)) { Stack.NCacheLog.Error("GMS.InstallView", "[" + local_addr + "] received view has the same members as current view;" + " discarding it (current vid: " + view_id + ", new vid: " + vid + ')'); Event viewEvt = new Event(Event.VIEW_CHANGE_OK, null, Priority.Critical); //#usama@15-4-2013 joining, leaving and tmp_members are needed to be synchronized even if view is same Global.ICollectionSupport.RemoveAll(joining, mbrs); // remove all members in mbrs from joining // remove all elements from 'leaving' that are not in 'mbrs' Global.ICollectionSupport.RetainAll(leaving, mbrs); tmp_members.add(joining); // add members that haven't yet shown up in the membership tmp_members.remove(leaving); // remove members that haven't yet been removed from the membership passDown(viewEvt); return; } } //========================================= // Stack.NCacheLog.CriticalInfo("GMS.InstallView", "Installing view in gms"); if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("GMS.InstallView " + new_view.ToString() + "\\n" + "seq tble : " + new_view.SequencerTbl.Count); this._subGroupMbrsMap = new_view.SequencerTbl.Clone() as System.Collections.Hashtable; this._mbrSubGroupMap = new_view.MbrsSubgroupMap.Clone() as System.Collections.Hashtable; //========================================= // serialize access to views // assign new_view to view_id view_id = vid.Copy(); Stack.NCacheLog.CriticalInfo("GMS.InstallView", "=== View ID = " + view_id.ToString()); // Set the membership. Take into account joining members if (mbrs != null && mbrs.Count > 0) { for (int i = 0; i < members.size(); i++) { Address mbr = members.elementAt(i); if (!mbrs.Contains(mbr)) RemoveGmsId(mbr); } Hashtable gmsIds = new_view.GmsIds; if (gmsIds != null) { IDictionaryEnumerator ide = gmsIds.GetEnumerator(); while (ide.MoveNext()) { if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("GMS.InstallView", "mbr = " + ide.Key + " ; gms_id = " + ide.Value); AddGmsId((Address)ide.Key, (string)ide.Value); } } for (int i = 0; i < mbrs.Count; i++) { Stack.NCacheLog.CriticalInfo("GMS.InstallView", "Members.set = " + mbrs[i] != null ? mbrs[i].ToString() : null); } members.set(mbrs); tmp_members.set(members); Global.ICollectionSupport.RemoveAll(joining, mbrs); // remove all members in mbrs from joining // remove all elements from 'leaving' that are not in 'mbrs' Global.ICollectionSupport.RetainAll(leaving, mbrs); tmp_members.add(joining); // add members that haven't yet shown up in the membership tmp_members.remove(leaving); // remove members that haven't yet been removed from the membership // add to prev_members for (System.Collections.IEnumerator it = mbrs.GetEnumerator(); it.MoveNext(); ) { Address addr = (Address)it.Current; if (!prev_members.contains(addr)) prev_members.add(addr); } } // Send VIEW_CHANGE event up and down the stack: if (Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("GMS.installView", "broadcasting view change within stack"); coord = determineCoordinator(); // changed on suggestion by yaronr and Nicolas Piedeloupe if (coord != null && coord.Equals(local_addr) && !haveCoordinatorRole()) { becomeCoordinator(); } else { if (haveCoordinatorRole() && !local_addr.Equals(coord)) becomeParticipant(); } if (string.IsNullOrEmpty(new_view.BridgeSourceCacheId)) new_view.BridgeSourceCacheId = impl.UniqueId; MarkStateTransferInProcess(); Event view_event = new Event(Event.VIEW_CHANGE, new_view.Clone(), Priority.Critical); passDown(view_event); // needed e.g. by failure detector or UDP } } finally { } }
/// <summary> Sets the new view and sends a VIEW_CHANGE event up and down the stack. If the view is a MergeView (subclass /// of View), then digest will be non-null and has to be set before installing the view. /// </summary> public virtual void installView(View new_view, Digest digest) { if (digest != null) mergeDigest(digest); installView(new_view); }
/// <summary> Computes the new view (including the newly joined member) and get the digest from PBCAST. /// Returns both in the form of a JoinRsp /// </summary> public override JoinRsp handleJoin(Address mbr, string subGroup_name, bool isStartedAsMirror, string gmsId, ref bool acquireHashmap) { lock (this) { System.Collections.ArrayList new_mbrs = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(1)); View v = null; Digest d, tmp; gms.Stack.NCacheLog.CriticalInfo("CoordGmsImpl.handleJoin", "mbr=" + mbr); if (gms.local_addr.Equals(mbr)) { gms.Stack.NCacheLog.Error("CoordGmsImpl.handleJoin", "cannot join myself !"); return null; } if (gms.members.contains(mbr)) { gms.Stack.NCacheLog.Error("CoordGmsImpl.handleJoin()", "member " + mbr + " already present; returning existing view " + Global.CollectionToString(gms.members.Members)); acquireHashmap = false; View view = new View(gms.view_id, gms.members.Members); view.CoordinatorGmsId = gms.unique_id; JoinRsp rsp = new JoinRsp(view, gms.Digest); rsp.View.SequencerTbl = gms._subGroupMbrsMap; rsp.View.MbrsSubgroupMap = gms._mbrSubGroupMap; return rsp; // already joined: return current digest and membership } new_mbrs.Add(mbr); //===================================== // update the subGroupMbrsMap and mbrSubGroupMap if (gms._subGroupMbrsMap.Contains(subGroup_name)) { lock (gms._subGroupMbrsMap.SyncRoot) { System.Collections.ArrayList groupMbrs = (System.Collections.ArrayList)gms._subGroupMbrsMap[subGroup_name]; if (!groupMbrs.Contains(mbr)) groupMbrs.Add(mbr); } } else { lock (gms._subGroupMbrsMap.SyncRoot) { System.Collections.ArrayList groupMbrs = new System.Collections.ArrayList(); groupMbrs.Add(mbr); gms._subGroupMbrsMap[subGroup_name] = groupMbrs; } } if (!gms._mbrSubGroupMap.Contains(mbr)) { lock (gms._mbrSubGroupMap.SyncRoot) { gms._mbrSubGroupMap[mbr] = subGroup_name; } } //===================================== tmp = gms.Digest; // get existing digest if (tmp == null) { gms.Stack.NCacheLog.Error("CoordGmsImpl.handleJoin", "received null digest from GET_DIGEST: will cause JOIN to fail"); return null; } gms.Stack.NCacheLog.Debug("got digest=" + tmp); d = new Digest(tmp.size() + 1); // create a new digest, which contains 1 more member d.add(tmp); // add the existing digest to the new one d.add(mbr, 0, 0); // ... and add the new member. it's first seqno will be 1 v = gms.getNextView(new_mbrs, null, null); v.SequencerTbl = gms._subGroupMbrsMap; v.MbrsSubgroupMap = gms._mbrSubGroupMap; v.AddGmsId(mbr, gmsId); //add coordinator own's gms id[bug fix]; so that new member could know cordinator id v.AddGmsId(gms.local_addr, gms.unique_id); if (gms.GmsIds != null) { Hashtable gmsIds = gms.GmsIds.Clone() as Hashtable; IDictionaryEnumerator ide = gmsIds.GetEnumerator(); while (ide.MoveNext()) { v.AddGmsId((Address)ide.Key,(string) ide.Value); } } gms.Stack.NCacheLog.Debug("joined member " + mbr + ", view is " + v); return new JoinRsp(v, d); } }
/// <summary> <tt>Event.VIEW_CHANGE</tt> event received from a layer below /// <p> /// Mark all responses from members that are not in new_view as /// NOT_RECEIVED. /// /// </summary> public virtual void receiveView(View new_view) { RequestEntry entry; System.Collections.ArrayList copy; ArrayList oldMembers = new ArrayList(); // copy so we don't run into bug #761804 - Bela June 27 2003 req_lock.AcquireReaderLock(Timeout.Infinite); try { if (new_view != null) { if(members != null) { foreach(Address member in members) { if(!new_view.Members.Contains(member)) oldMembers.Add(member); } } members = new_view.Members.Clone() as ArrayList; } copy = new System.Collections.ArrayList(requests.Values); } finally { req_lock.ReleaseReaderLock(); } for (System.Collections.IEnumerator it = copy.GetEnumerator(); it.MoveNext(); ) { entry = (RequestEntry) it.Current; if (entry.coll != null) entry.coll.viewChange(new_view); } //Remove request status information for all requests from the old members. lock (_reqStatusTable.SyncRoot) { if (members != null) { foreach (Address oldmember in oldMembers) { _reqStatusTable.Remove(oldmember); } } } }
/// <summary> Called by the GMS when a VIEW is received.</summary> /// <param name="new_view">The view to be installed /// </param> /// <param name="digest"> If view is a MergeView, digest contains the seqno digest of all members and has to /// be set by GMS /// </param> public override void handleViewChange(View new_view, Digest digest) { System.Collections.ArrayList mbrs = new_view.Members; if (digest != null) { gms.Stack.NCacheLog.Debug("view=" + new_view + ", digest=" + digest); } else { gms.Stack.NCacheLog.Debug("view=" + new_view); } if (leaving && !mbrs.Contains(gms.local_addr)) return; gms.installView(new_view, digest); lock (viewRejectingMembers.SyncRoot) { //we handle the request of those nodes who have rejected our this view Address rejectingMbr; for (int i = 0; i < viewRejectingMembers.Count; i++) { rejectingMbr = viewRejectingMembers[i] as Address; handleViewRejected(rejectingMbr); } viewRejectingMembers.Clear(); } }
public JoinRsp(View v, Digest d) { view = v; digest = d; }
/// <summary> Does nothing. Discards all views while still client.</summary> public override void handleViewChange(View new_view, Digest digest) { lock (this) { gms.Stack.NCacheLog.Debug("pb.ClientGmsImpl.handleViewChange()", "view " + Global.CollectionToString(new_view.Members) + " is discarded as we are not a participant"); } gms.passDown(new Event(Event.VIEW_CHANGE_OK, new object(),Priority.Critical)); }
public JoinRsp(View v, Digest d, JoinResult result) { view = v; digest = d; joinResult = result; }
/// <summary> /// Notify the target object of a change of membership. /// </summary> /// <param name="new_view">New view of group</param> void MembershipListener.viewAccepted(View newView) { System.Collections.ArrayList joined_mbrs, left_mbrs, tmp; ArrayList joining_mbrs = new ArrayList(); lock (viewMutex) { object tmp_mbr; if (newView == null) return; NCacheLog.CriticalInfo("ClusterService.ViewAccepted", newView.ToString()); tmp = newView.Members; if (newView.Vid != null) { this._lastViewId = newView.Vid.Id; } // get new members joined_mbrs = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); for (int i = 0; i < tmp.Count; i++) { tmp_mbr = tmp[i]; if (!_members.Contains(tmp_mbr)) joined_mbrs.Add(tmp_mbr); } int localIndex = 0; if (joined_mbrs.Contains(LocalAddress)) localIndex = joined_mbrs.IndexOf(LocalAddress); for (int i = localIndex; i < joined_mbrs.Count; i++) { joining_mbrs.Add(joined_mbrs[i]); } // get members that left left_mbrs = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); for (int i = 0; i < _members.Count; i++) { tmp_mbr = _members[i]; if (!tmp.Contains(tmp_mbr)) left_mbrs.Add(tmp_mbr); } // adjust our own membership _members.Clear(); _members.AddRange(tmp); //muds: //pick the map from the view and send it to cache. //if i am the only member, i can build the map locally. if (newView.DistributionMaps == null && newView.Members.Count == 1) { if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ClusterService.viewAccepted()", "I am the only member in the view so, building map myself"); PartNodeInfo affectedNode = new PartNodeInfo(LocalAddress, _subgroupid, true); DistributionInfoData info = new DistributionInfoData(DistributionMode.OptimalWeight, ClusterActivity.NodeJoin, affectedNode); DistributionMaps maps = _distributionPolicyMbr.GetDistributionMaps(info); if (maps != null) { _distributionPolicyMbr.HashMap = maps.Hashmap; _distributionPolicyMbr.BucketsOwnershipMap = maps.BucketsOwnershipMap; } } else { if (newView.MirrorMapping != null) { _distributionPolicyMbr.InstallMirrorMap(newView.MirrorMapping); NCacheLog.Info("ClusterService.viewAccepted()", "New MirrorMap installed."); } if (newView.DistributionMaps != null) { _distributionPolicyMbr.InstallHashMap(newView.DistributionMaps, left_mbrs); if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ClusterService.viewAccepted()", "New hashmap installed"); } } lock (_servers.SyncRoot) { if (left_mbrs.Count > 0) { for (int i = left_mbrs.Count - 1; i >= 0; i--) { Address ipAddr = (Address)((Address)left_mbrs[i]); if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ClusterService.viewAccepted", ipAddr.AdditionalData.Length.ToString()); ipAddr = (Address)ipAddr.Clone(); if (_servers.Contains(ipAddr)) _servers.Remove(ipAddr); OnMemberLeft(ipAddr, CompactBinaryFormatter.FromByteBuffer(ipAddr.AdditionalData, _context.SerializationContext) as NodeIdentity); ipAddr.AdditionalData = null; } } _validMembers = (ArrayList)_members.Clone(); if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ClusterService.viewAccepted", joining_mbrs.Count.ToString()); if (joined_mbrs.Count > 0) { for (int i = 0; i < joined_mbrs.Count; i++) { Address ipAddr = (Address)joined_mbrs[i]; if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ClusterService.viewAccepted", ipAddr.AdditionalData.Length.ToString()); ipAddr = (Address)ipAddr.Clone(); if (OnMemberJoined(ipAddr, CompactBinaryFormatter.FromByteBuffer(ipAddr.AdditionalData, _context.SerializationContext) as NodeIdentity, joining_mbrs)) { if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ClusterServices.ViewAccepted", ipAddr.ToString() + " is added to _servers list."); _servers.Add(ipAddr); } ipAddr.AdditionalData = null; } } } if (String.IsNullOrEmpty(_bridgeSourceCacheId)) _bridgeSourceCacheId = newView.BridgeSourceCacheId; OnAfterMembershipChange(); } }
public void Deserialize(CompactReader reader) { view = reader.ReadObject() as View; digest = reader.ReadObject() as Digest; joinResult = (JoinResult)reader.ReadObject(); }
public override void handleResetOnNodeRejoining(Address sender, Address node, View view) { gms.handleResetOnNodeRejoining(sender, node,view); }
/// <summary> Called by join(). Installs the view returned by calling Coord.handleJoin() and /// becomes coordinator. /// </summary> private bool installView(View new_view, bool isPOR) { if (isPOR) { Address replica = (Address)gms.members.Members[1]; SendCheckClusterHealth(replica, new_view.Coordinator); } ArrayList mems = new_view.Members; gms.Stack.NCacheLog.Debug("pb.ClientGmsImpl.installView()", "new_view=" + new_view); if (gms.local_addr == null || mems == null || !mems.Contains(gms.local_addr)) { gms.Stack.NCacheLog.Error("pb.ClientGmsImpl.installView()", "I (" + gms.local_addr + ") am not member of " + Global.CollectionToString(mems) + ", will not install view"); return false; } //Cast view to the replica node as well gms.installView(new_view); gms.becomeParticipant(); gms.Stack.IsOperational = true; Util.Util.sleep(gms.join_retry_timeout); return true; }
public virtual void handleResetOnNodeRejoining(Address sender, Address node,View view) { }
/// <summary> Get the view and digest and send back both (MergeData) in the form of a MERGE_RSP to the sender. /// If a merge is already in progress, send back a MergeData with the merge_rejected field set to true. /// </summary> public override void handleMergeRequest(Address sender, object merge_id) { Digest digest; View view; if (sender == null) { gms.Stack.NCacheLog.Error("CoordGmsImpl.handleMergeRequest", "sender == null; cannot send back a response"); return; } if (merging) { gms.Stack.NCacheLog.Error("CoordGmsImpl.handleMergeRequest", "merge already in progress"); sendMergeRejectedResponse(sender); return; } merging = true; this.merge_id = merge_id; gms.Stack.NCacheLog.Debug("CoordGmsImpl.handleMergeRequest", "sender=" + sender + ", merge_id=" + merge_id); digest = gms.Digest; view = new View(gms.view_id.Copy(), gms.members.Members); view.CoordinatorGmsId = gms.unique_id; sendMergeResponse(sender, view, digest); }
/// <summary> creates a copy of this view</summary> /// <returns> a copy of this view /// </returns> public virtual object Clone() { ViewId vid2 = vid != null?(ViewId) vid.Clone():null; System.Collections.ArrayList members2 = _members != null?(System.Collections.ArrayList) _members.Clone():null; View v = new View(vid2, members2); if(SequencerTbl != null) v.SequencerTbl = SequencerTbl.Clone() as Hashtable; if (MbrsSubgroupMap != null) v.MbrsSubgroupMap = MbrsSubgroupMap.Clone() as Hashtable; v._coordinatorGmsId = _coordinatorGmsId; if (DistributionMaps != null) v.DistributionMaps = DistributionMaps.Clone() as DistributionMaps; if (MirrorMapping != null) v.MirrorMapping = MirrorMapping; v._bridgeSourceCacheId = _bridgeSourceCacheId; if (nodeGmsIds != null) v.nodeGmsIds = nodeGmsIds.Clone() as Hashtable; return (v); }
internal virtual MergeData getMergeResponse(Address sender, object merge_id) { Digest digest; View view; MergeData retval; if (sender == null) { gms.Stack.NCacheLog.Error("CoordGmsImpl.getMergeResponse", "sender == null; cannot send back a response"); return null; } if (merging) { gms.Stack.NCacheLog.Error("CoordGmsImpl.getMergeResponse", "merge already in progress"); retval = new MergeData(sender, null, null); retval.merge_rejected = true; return retval; } merging = true; this.merge_id = merge_id; gms.Stack.NCacheLog.Debug("sender=" + sender + ", merge_id=" + merge_id); digest = gms.Digest; view = new View(gms.view_id.Copy(), gms.members.Members); retval = new MergeData(sender, view, digest); retval.view = view; retval.digest = digest; return retval; }
public static void WriteView(CompactWriter writer, View v) { byte isNull = 1; if (v == null) writer.Write(isNull); else { isNull = 0; writer.Write(isNull); v.Serialize(writer); } return; }
public virtual void castViewChange(View new_view) { castViewChange(new_view, null); }