Exemple #1
0
        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");
                }
            }
        }
Exemple #2
0
		public abstract void  handleViewChange(View new_view, Digest digest);
Exemple #3
0
		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;
        }
Exemple #6
0
        /// <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));
        }
Exemple #7
0
		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);

		}
Exemple #8
0
		/// <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);
			}
		}
Exemple #9
0
		/// <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());					
				}
			}
		}
Exemple #10
0
        /// <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);
            }
        }
Exemple #11
0
		/* ----------------------------------- 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; 
		}
Exemple #12
0
        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;
        }
Exemple #13
0
        /// <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
            {
            }
        }
Exemple #14
0
 /// <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);
 }
Exemple #15
0
        /// <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);
                    }
                }
            }
		}
Exemple #17
0
        /// <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();
            }
        }
Exemple #18
0
 public JoinRsp(View v, Digest d)
 {
     view = v;
     digest = d;
 }
Exemple #19
0
		/// <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));
		}
Exemple #20
0
 public JoinRsp(View v, Digest d, JoinResult result)
 {
     view = v;
     digest = d;
     joinResult = result;
 }
Exemple #21
0
        /// <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();
            }
        }
Exemple #22
0
 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);
 }
Exemple #24
0
        /// <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;
		}
Exemple #25
0
        public virtual void handleResetOnNodeRejoining(Address sender, Address node,View view)
        {

        }
Exemple #26
0
        /// <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);
        }
Exemple #27
0
		/// <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);
		}
Exemple #28
0
        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;
        }
Exemple #29
0
		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;
		}  		    
Exemple #30
0
 public virtual void castViewChange(View new_view)
 {
     castViewChange(new_view, null);
 }