Ejemplo n.º 1
0
        }         // only processed by coords

        public virtual void  handleMergeView(MergeData data, object merge_id)
        {
            ;
        }         // only processed by coords
Ejemplo n.º 2
0
        /// <summary> Sends the new view and digest to all subgroup coordinors in coords. Each coord will in turn
        /// <ol>
        /// <li>cast the new view and digest to all the members of its subgroup (MergeView)
        /// <li>on reception of the view, if it is a MergeView, each member will set the digest and install
        /// the new view
        /// </ol>
        /// </summary>
        internal virtual void sendMergeView(System.Collections.ArrayList coords, MergeData combined_merge_data)
        {
            Message msg;
            GMS.HDR hdr;
            Address coord;
            View v;
            Digest d;

            if (coords == null || combined_merge_data == null)
                return;
            v = combined_merge_data.view;
            d = combined_merge_data.digest;
            if (v == null || d == null)
            {
                gms.Stack.NCacheLog.Error("view or digest is null, cannot send consolidated merge view/digest");
                return;
            }

            for (int i = 0; i < coords.Count; i++)
            {
                coord = (Address)coords[i];
                msg = new Message(coord, null, null);
                hdr = new GMS.HDR(GMS.HDR.INSTALL_MERGE_VIEW);
                hdr.view = v;
                hdr.digest = d;
                hdr.merge_id = merge_id;
                msg.putHeader(HeaderType.GMS, hdr);
                gms.passDown(new Event(Event.MSG, msg));
            }
        }
Ejemplo n.º 3
0
		} // only processed by coords
		public virtual void  handleMergeView(MergeData data, object merge_id)
		{
			;
		} // only processed by coords
Ejemplo n.º 4
0
        /// <summary> Merge all MergeData. All MergeData elements should be disjunct (both views and digests). However,
        /// this method is prepared to resolve duplicate entries (for the same member). Resolution strategy for
        /// views is to merge only 1 of the duplicate members. Resolution strategy for digests is to take the higher
        /// seqnos for duplicate digests.<p>
        /// After merging all members into a Membership and subsequent sorting, the first member of the sorted membership
        /// will be the new coordinator.
        /// </summary>
        /// <param name="v">A list of MergeData items. Elements with merge_rejected=true were removed before. Is guaranteed
        /// not to be null and to contain at least 1 member.
        /// </param>
        internal virtual MergeData consolidateMergeData(System.Collections.ArrayList v)
        {
            MergeData ret = null;
            MergeData tmp_data;
            long logical_time = 0; // for new_vid
            ViewId new_vid, tmp_vid;
            MergeView new_view;
            View tmp_view;
            Membership new_mbrs = new Membership();
            int num_mbrs = 0;
            Digest new_digest = null;
            Address new_coord;
            System.Collections.ArrayList subgroups = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(11));
            // contains a list of Views, each View is a subgroup

            for (int i = 0; i < v.Count; i++)
            {
                tmp_data = (MergeData)v[i];

                gms.Stack.NCacheLog.Debug("merge data is " + tmp_data);

                tmp_view = tmp_data.View;
                if (tmp_view != null)
                {
                    tmp_vid = tmp_view.Vid;
                    if (tmp_vid != null)
                    {
                        // compute the new view id (max of all vids +1)
                        logical_time = System.Math.Max(logical_time, tmp_vid.Id);
                    }
                }
                // merge all membership lists into one (prevent duplicates)
                new_mbrs.add(tmp_view.Members);
                subgroups.Add(tmp_view.Clone());
            }

            // the new coordinator is the first member of the consolidated & sorted membership list
            new_mbrs.sort();
            num_mbrs = new_mbrs.size();
            new_coord = num_mbrs > 0 ? (Address)new_mbrs.elementAt(0) : null;
            if (new_coord == null)
            {
                gms.Stack.NCacheLog.Error("CoordGmsImpl.consolodateMergeData", "new_coord is null.");
                return null;
            }
            // should be the highest view ID seen up to now plus 1
            new_vid = new ViewId(new_coord, logical_time + 1);

            // determine the new view
            new_view = new MergeView(new_vid, new_mbrs.Members, subgroups);

            gms.Stack.NCacheLog.Debug("new merged view will be " + new_view);

            // determine the new digest
            new_digest = consolidateDigests(v, num_mbrs);
            if (new_digest == null)
            {
                gms.Stack.NCacheLog.Error("CoordGmsImpl.consolidateMergeData", "digest could not be consolidated.");
                return null;
            }

            gms.Stack.NCacheLog.Debug("consolidated digest=" + new_digest);

            ret = new MergeData(gms.local_addr, new_view, new_digest);
            return ret;
        }
Ejemplo n.º 5
0
 /// <summary> If merge_id != this.merge_id --> discard
 /// Else cast the view/digest to all members of this group.
 /// </summary>
 public override void handleMergeView(MergeData data, object merge_id)
 {
     if (merge_id == null || this.merge_id == null || !this.merge_id.Equals(merge_id))
     {
         gms.Stack.NCacheLog.Error("CoordGmsImpl.handleMergeView", "merge_ids don't match (or are null); merge view discarded");
         return;
     }
     gms.castViewChange(data.view, data.digest);
     merging = false;
     merge_id = null;
 }
Ejemplo n.º 6
0
        public override void handleMergeResponse(MergeData data, object merge_id)
        {
            if (data == null)
            {
                gms.Stack.NCacheLog.Error("CoordGmsImpl.handleMergeResponse", "merge data is null");
                return;
            }
            if (merge_id == null || this.merge_id == null)
            {

                gms.Stack.NCacheLog.Error("CoordGmsImpl.handleMergeResponse", "merge_id (" + merge_id + ") or this.merge_id (" + this.merge_id + ") == null (sender=" + data.Sender + ").");
                return;
            }

            if (!this.merge_id.Equals(merge_id))
            {
                gms.Stack.NCacheLog.Error("CoordGmsImpl.handleMergeResponse", "this.merge_id (" + this.merge_id + ") is different from merge_id (" + merge_id + ')');
                return;
            }

            lock (merge_rsps.SyncRoot)
            {
                if (!merge_rsps.Contains(data))
                {
                    merge_rsps.Add(data);
                    System.Threading.Monitor.PulseAll(merge_rsps.SyncRoot);
                }
            }
        }
Ejemplo n.º 7
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;
        }
Ejemplo n.º 8
0
        public override void up(Event evt)
        {
            object obj;
            Message msg;
            HDR hdr;
            MergeData merge_data;

            switch (evt.Type)
            {


                case Event.MSG:
                    msg = (Message)evt.Arg;

                    obj = msg.getHeader(HeaderType.GMS);
                    if (obj == null || !(obj is HDR))
                        break;
                    hdr = (HDR)msg.removeHeader(HeaderType.GMS);
                    switch (hdr.type)
                    {

                        case HDR.JOIN_REQ:
                            object[] args = new object[4];
                            args[0] = hdr.mbr;
                            args[1] = hdr.subGroup_name;
                            args[2] = hdr.isStartedAsMirror;
                            args[3] = hdr.GMSId;
                            ThreadPool.QueueUserWorkItem(new WaitCallback(handleJoinrequestAsync), args);
                           
                            break;

                        case HDR.SPECIAL_JOIN_REQUEST:
                            HandleSpecialJoinRequest(hdr.mbr, hdr.GMSId);
                            break;

                        case HDR.JOIN_RSP:
                            MarkStateTransferInProcess();
                            impl.handleJoinResponse(hdr.join_rsp);
                            break;

                        case HDR.LEAVE_REQ:
                            Stack.NCacheLog.Debug("received LEAVE_REQ " + hdr + " from " + msg.Src);

                            if (hdr.mbr == null)
                            {
                                Stack.NCacheLog.Error( "LEAVE_REQ's mbr field is null");
                                return;
                            }
                           
                            if (isPartReplica && IsCoordinator)
                            {
                                //if replica node on the coordinator is leaving then send a special event to TCP
                                //to mark himself leaving. This way other node asking for death status through keep
                                //alive will get dead status.
                                if (hdr.mbr != null && hdr.mbr.IpAddress.Equals(local_addr.IpAddress))
                                {
                                    down(new Event(Event.I_AM_LEAVING));
                                }
                            }
                            ThreadPool.QueueUserWorkItem(new WaitCallback(handleLeaveAsync), new object[] { hdr.mbr, false });
                            
                            break;

                        case HDR.LEAVE_RSP:
                            impl.handleLeaveResponse();
                            break;

                        case HDR.VIEW_RESPONSE:
                            if (_promise != null)
                                _promise.SetResult(hdr.arg);
                            break;

                        case HDR.VIEW:
                            if (hdr.view == null)
                            {
                                Stack.NCacheLog.Error("[VIEW]: view == null");
                                return;
                            }
                            else
                                Stack.NCacheLog.CriticalInfo("gms.Up", "received view from :" + msg.Src + " ; view = " + hdr.view);  
                            impl.handleViewChange(hdr.view, hdr.digest);
                            break;


                        case HDR.MERGE_REQ:
                            impl.handleMergeRequest(msg.Src, hdr.merge_id);
                            break;


                        case HDR.MERGE_RSP:
                            merge_data = new MergeData(msg.Src, hdr.view, hdr.digest);
                            merge_data.merge_rejected = hdr.merge_rejected;
                            impl.handleMergeResponse(merge_data, hdr.merge_id);
                            break;


                        case HDR.INSTALL_MERGE_VIEW:
                            impl.handleMergeView(new MergeData(msg.Src, hdr.view, hdr.digest), hdr.merge_id);
                            break;


                        case HDR.CANCEL_MERGE:
                            impl.handleMergeCancelled(hdr.merge_id);
                            break;

                        case HDR.CAN_NOT_CONNECT_TO:
                            impl.handleCanNotConnectTo(msg.Src, hdr.nodeList);
                            break;

                        case HDR.LEAVE_CLUSTER:
                           
                            string gmsId = hdr.arg as string;//reported gms id
                            string myGmsId = GetNodeGMSId(local_addr);

                            if (gmsId != null && myGmsId != null && gmsId.Equals(myGmsId))
                            {
                                ThreadPool.QueueUserWorkItem(new WaitCallback(handleLeaveClusterRequestAsync), hdr.mbr);
                            }
                            break;

                        case HDR.CONNECTION_BROKEN:
                            impl.handleConnectionBroken(msg.Src, hdr.mbr);
                            break;

                        case HDR.VIEW_REJECTED:
                            impl.handleViewRejected(hdr.mbr);
                            break;

                        case HDR.INFORM_NODE_REJOINING:
                            impl.handleInformNodeRejoining(msg.Src, hdr.mbr);
                            break;

                        case HDR.RESET_ON_NODE_REJOINING:
                            impl.handleResetOnNodeRejoining(msg.Src, hdr.mbr, hdr.view);
                            break;

                        case HDR.RE_CHECK_CLUSTER_HEALTH:
                           
                            Thread t = new Thread(new ParameterizedThreadStart(impl.ReCheckClusterHealth));
                            t.Start(hdr.mbr);
                           
                            break;

                        case HDR.INFORM_ABOUT_NODE_DEATH:
                            //Replica is not supposed to handle this event
                            if (isPartReplica && _startedAsMirror) break;

                            impl.handleInformAboutNodeDeath(msg.Src, (Address)hdr.arg);
                            break;

                        case HDR.IS_NODE_IN_STATE_TRANSFER:
                            impl.handleIsClusterInStateTransfer(msg.Src);
                            break;

                        case HDR.IS_NODE_IN_STATE_TRANSFER_RSP:
                            if (_stateTransferPromise != null)
                            {
                                if(Stack.NCacheLog.IsInfoEnabled) Stack.NCacheLog.Info("gms.UP", "(state transfer rsp) sender: " + msg.Src + " ->" + hdr.arg);
                                _stateTransferPromise.SetResult(hdr.arg);
                            }
                            break;

                        default:
                            Stack.NCacheLog.Error( "HDR with type=" + hdr.type + " not known");
                            break;

                    }

                   
                    return; // don't pass up


                case Event.CONNECT_OK:
                // sent by someone else, but WE are responsible for sending this !
                case Event.DISCONNECT_OK:  // dito (e.g. sent by UDP layer). Don't send up the stack
                    return;

                case Event.GET_NODE_STATUS_OK:
                    lock (suspect_verify_mutex)
                    {
                        NodeStatus status = evt.Arg as NodeStatus;
                        if (status.Node != null && status.Node.Equals(nodeTobeSuspect))
                        {
                            nodeStatus = status;
                            Monitor.PulseAll(suspect_verify_mutex);
                        }
                    }
                    break;

                case Event.SET_LOCAL_ADDRESS:
                    local_addr = (Address)evt.Arg;
                  
                    break; // pass up


                case Event.SUSPECT:
                    ThreadPool.QueueUserWorkItem(new WaitCallback(handleSuspectAsync), evt.Arg);
                    break; // pass up


                case Event.UNSUSPECT:
                    impl.unsuspect((Address)evt.Arg);
                    return; // discard


                case Event.MERGE:
                    impl.merge((System.Collections.ArrayList)evt.Arg);
                    return; // don't pass up

                case Event.CONNECTION_FAILURE:
                   
                    impl.handleConnectionFailure(evt.Arg as ArrayList);
                    return;//dont passup

                case Event.NODE_REJOINING:
                   
                    impl.handleNodeRejoining(evt.Arg as Address);
                    return;

                case Event.CONNECTION_BREAKAGE:
                    Address node = evt.Arg as Address;
                    if (!disconnected_nodes.Contains(node))
                        disconnected_nodes.Add(node);
                    break;

                case Event.CONNECTION_RE_ESTABLISHED:
                    node = evt.Arg as Address;
                    if (disconnected_nodes.Contains(node))
                        disconnected_nodes.Remove(node);
                    break;
            }

            if (impl.handleUpEvent(evt))
                passUp(evt);
        }