예제 #1
0
파일: GMS.cs 프로젝트: paulorades/externals
        /// <summary>
        /// Computes the next view, removes old and suspected members, adds new members.
        /// </summary>
        /// <param name="new_mbrs">New members to be added to the view</param>
        /// <param name="old_mbrs">Old members to be removed from the view</param>
        /// <param name="suspected_mbrs">Suspected members to be removed from the view</param>
        /// <returns>The new View</returns>
        public View getNextView(ArrayList new_mbrs, ArrayList old_mbrs, ArrayList suspected_mbrs)
        {
            ArrayList  mbrs;
            long       vid = 0;
            View       v;
            Membership tmp_mbrs = null;
            Address    tmp_mbr;

            lock (members)
            {
                if (view_id == null)
                {
                    return(null);                                // this should *never* happen !
                }
                vid   = Math.Max(view_id.getId(), ltime) + 1;
                ltime = vid;

                if (Trace.trace)
                {
                    Trace.info("GMS.getNextView()", "VID=" + vid + ", current members=" +
                               printMembers(members.getMembers()) +
                               ", new_mbrs=" + printMembers(new_mbrs) +
                               ", old_mbrs=" + printMembers(old_mbrs) + ", suspected_mbrs=" +
                               printMembers(suspected_mbrs));
                }

                tmp_mbrs = tmp_members.copy();                // always operate on the temporary membership
                tmp_mbrs.remove(suspected_mbrs);
                tmp_mbrs.remove(old_mbrs);
                tmp_mbrs.add(new_mbrs);
                mbrs = (ArrayList)tmp_mbrs.getMembers();
                v    = new View(local_addr, vid, mbrs);

                // Update membership
                tmp_members.set(mbrs);

                // Update joining list
                if (new_mbrs != null)
                {
                    for (int i = 0; i < new_mbrs.Count; i++)
                    {
                        tmp_mbr = (Address)new_mbrs[i];
                        if (!joining.Contains(tmp_mbr))
                        {
                            joining.Add(tmp_mbr);
                        }
                    }
                }

                if (Trace.trace)
                {
                    Trace.info("GMS.getNextView()", "new view is " + v);
                }
                return(v);
            }
        }
예제 #2
0
파일: GMS.cs 프로젝트: paulorades/externals
        /// <summary>
        /// Sets the new view and sends a VIEW_CHANGE event up and down the stack.
        /// </summary>
        /// <param name="new_view">New View to install</param>
        public void installView(View new_view)
        {
            Address   coord;
            int       rc;
            ViewId    vid  = new_view.getVid();
            ArrayList mbrs = new_view.getMembers();

            lock (members)
            {                                         // serialize access to views
                ltime = Math.Max(vid.getId(), 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 (Trace.trace)
                {
                    Trace.info("GMS.installView()", "View to install contains: " + new_view.ToString());
                }
                if (checkSelfInclusion(mbrs) == false)
                {
                    if (Trace.trace)
                    {
                        Trace.warn("GMS.installView()",
                                   "checkSelfInclusion() failed, not a member of view " + mbrs + "; discarding view");
                    }
                    if (shun)
                    {
                        if (Trace.trace)
                        {
                            Trace.warn("GMS.installView()", "I'm being shunned, will leave and rejoin group");
                        }
                        passUp(new Event(Event.EXIT));
                    }
                    return;
                }



                // 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)
                    {
                        if (Trace.trace)
                        {
                            Trace.error("GMS.installView()", "received view <= current view;" +
                                        " discarding it ! (current vid: " + view_id + ", new vid: " + vid + ")");
                        }
                        return;
                    }
                }

                if (Trace.trace)
                {
                    Trace.info("GMS.installView()", "view is " + new_view);
                }

                // assign new_view to view_id
                view_id = vid.Copy();

                // Set the membership. Take into account joining members
                if (mbrs != null && mbrs.Count > 0)
                {
                    members.set(mbrs);
                    tmp_members.set(members);
                    foreach (Object obj in mbrs)
                    {
                        joining.Remove(obj);                      // remove all members in mbrs from joining
                    }
                    tmp_members.add(joining);                     // adjust temporary membership
                }

                // Send VIEW_CHANGE event up and down the stack:
                Event view_event = new Event(Event.VIEW_CHANGE, (View)new_view.copy());
                passDown(view_event);                 // needed e.g. by failure detector or UDP
                passUp(view_event);

                coord = determineCoordinator();
                if (coord != null && coord.Equals(local_addr) && !(coord.Equals(vid.getCoordAddress())))
                {
                    becomeCoordinator();
                }
                else
                {
                    if (haveCoordinatorRole() && !local_addr.Equals(coord))
                    {
                        becomeParticipant();
                    }
                }
            }
        }