KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > protocols > CoordGmsImpl


1 // $Id: CoordGmsImpl.java,v 1.7 2004/09/23 16:29:41 belaban Exp $
2

3 package org.jgroups.protocols;
4
5 import org.jgroups.Address;
6 import org.jgroups.Event;
7 import org.jgroups.View;
8 import org.jgroups.ViewId;
9 import org.jgroups.blocks.GroupRequest;
10 import org.jgroups.blocks.MethodCall;
11
12 import java.util.Collections JavaDoc;
13 import java.util.HashSet JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.Vector JavaDoc;
16
17
18 public class CoordGmsImpl extends GmsImpl {
19     boolean leaving=false;
20     boolean received_last_view=false;
21     final Object JavaDoc leave_mutex=new Object JavaDoc();
22
23
24     public CoordGmsImpl(GMS g) {
25         gms=g;
26     }
27
28
29     public void init() {
30         leaving=false;
31         received_last_view=false;
32     }
33
34
35     public void join(Address mbr) {
36         wrongMethod("join");
37     }
38
39
40     /**
41      * The coordinator itself wants to leave the group
42      */

43     public void leave(Address mbr) {
44         if(mbr.equals(gms.local_addr))
45             leaving=true;
46
47         handleLeave(mbr, false); // regular leave
48
synchronized(leave_mutex) {
49             if(leaving && received_last_view) // handleViewChange() has acquired leave_mutex before us...
50
return;
51             try {
52                 leave_mutex.wait(gms.leave_timeout); // will be notified by handleViewChange()
53
}
54             catch(Exception JavaDoc e) {
55             }
56         }
57     }
58
59
60     public void suspect(Address mbr) {
61         handleSuspect(mbr);
62     }
63
64
65     /**
66      * Invoked upon receiving a MERGE event from the MERGE layer. We have found a partition and
67      * should merge with them, then I will become a Participant.
68      *
69      * @param other_coords A list of other coordinators found. In the current implementation the list
70      * only has a single element
71      */

72     public void merge(Vector JavaDoc other_coords) {
73         View new_view=null;
74         Address other_coord=other_coords != null? (Address)other_coords.elementAt(0) : null;
75
76          if(log.isInfoEnabled()) log.info("other_coord = " + other_coord);
77         try {
78             MethodCall call=new MethodCall("handleMerge", new Object JavaDoc[]{gms.view_id, gms.members.getMembers()},
79                     new String JavaDoc[]{ViewId.class.getName(), Vector JavaDoc.class.getName()});
80             new_view=(View)gms.callRemoteMethod(other_coord, call, GroupRequest.GET_ALL, 0);
81         }
82         catch(Exception JavaDoc ex) {
83              if(log.isErrorEnabled()) log.error("timed out or was suspected");
84             return;
85         }
86         if(new_view == null) {
87              if(log.isWarnEnabled()) log.warn("received a Merge Denied");
88             gms.passDown(new Event(Event.MERGE_DENIED));
89             return; //Merge denied
90
}
91
92         //Flushing my old view
93
gms.flush(gms.members.getMembers(), null);
94         MethodCall call=new MethodCall("handleViewChange", new Object JavaDoc[]{new_view.getVid(), new_view.getMembers()},
95                 new String JavaDoc[]{ViewId.class.getName(), Vector JavaDoc.class.getName()});
96         gms.callRemoteMethods(gms.members.getMembers(), call, GroupRequest.GET_ALL, 0);
97         gms.becomeParticipant();
98          if(log.isInfoEnabled()) log.info("merge done");
99     }
100
101
102     public synchronized boolean handleJoin(Address mbr) {
103         Vector JavaDoc new_mbrs=new Vector JavaDoc(1);
104
105         if(log.isInfoEnabled()) log.info("received JOIN request from " + mbr);
106         if(gms.local_addr.equals(mbr)) {
107             if(log.isErrorEnabled()) log.error("cannot join myself !");
108             return false;
109         }
110         if(gms.members.contains(mbr)) {
111             if(log.isWarnEnabled()) log.warn("member " + mbr + " already present !");
112             return true; // already joined
113
}
114
115         new_mbrs.addElement(mbr);
116         gms.castViewChange(new_mbrs, null, null);
117         return true;
118     }
119
120
121     /**
122      * Exclude <code>mbr</code> from the membership. If <code>suspected</code> is true, then
123      * this member crashed and therefore is forced to leave, otherwise it is leaving voluntarily.
124      */

125     public synchronized void handleLeave(Address mbr, boolean suspected) {
126         Vector JavaDoc v=new Vector JavaDoc(1); // contains either leaving mbrs or suspected mbrs
127
if(!gms.members.contains(mbr)) {
128              if(log.isErrorEnabled()) log.error("mbr " + mbr + " is not a member !");
129             return;
130         }
131         v.addElement(mbr);
132         if(suspected)
133             gms.castViewChange(null, null, v);
134         else
135             gms.castViewChange(null, v, null);
136     }
137
138
139     public void handleViewChange(ViewId new_view, Vector JavaDoc mbrs) {
140         if(leaving) {
141             if(mbrs.contains(gms.local_addr)) {
142                 if(log.isWarnEnabled()) log.warn("received view in which I'm still a member, cannot quit yet");
143                 gms.installView(new_view, mbrs); // +++ modify
144
}
145             else {
146                 synchronized(leave_mutex) {
147                     received_last_view=true;
148                     leave_mutex.notifyAll();
149                 }
150             }
151             return;
152         }
153         gms.installView(new_view, mbrs); // +++ modify
154
}
155
156
157     /**
158      * Invoked by another coordinator that asks to merge its view with mine.
159      * I 'll be the new coordinator.
160      * We should flush our view, install a new view with all the members and
161      * return the new view that will be installed by the other coordinator before
162      * becoming a participant.
163      */

164     public synchronized View handleMerge(ViewId other_vid, Vector JavaDoc other_mbrs) {
165
166             if(log.isInfoEnabled()) log.info("other_vid=" + other_vid + " , other_mbrs=" + other_mbrs);
167
168         //Check that the views are disjoint otherwire return null (means MERGE_DENIED)
169
for(Iterator JavaDoc i=other_mbrs.iterator(); i.hasNext();) {
170             if(gms.members.contains((Address)i.next())) {
171                 gms.passDown(new Event(Event.MERGE_DENIED));
172                 return null;
173             }
174         }
175
176         //Compute new View
177
ViewId vid=new ViewId(gms.local_addr, Math.max(other_vid.getId() + 1, gms.ltime + 1));
178         HashSet JavaDoc members=new HashSet JavaDoc(gms.members.getMembers());
179         members.addAll(other_mbrs);
180         Vector JavaDoc new_mbrs=new Vector JavaDoc(members);
181         Collections.sort(new_mbrs);
182         View new_view=new View(vid, new_mbrs);
183
184         //Flush my view
185
gms.flush(gms.members.getMembers(), null);
186
187         //Install new view
188
MethodCall call=new MethodCall("handleViewChange", new Object JavaDoc[]{vid, new_mbrs},
189                 new String JavaDoc[]{ViewId.class.getName(), Vector JavaDoc.class.getName()});
190         gms.callRemoteMethods(gms.members.getMembers(), call, GroupRequest.GET_ALL, 0);
191         return new_view;
192     }
193
194
195     public void handleSuspect(Address mbr) {
196         if(mbr.equals(gms.local_addr)) {
197             if(log.isErrorEnabled()) log.error("I am the coord and am suspected: am not quitting !");
198             return;
199         }
200         handleLeave(mbr, true); // irregular leave - forced
201
}
202
203
204 }
205
Popular Tags