1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package jgroup.relacs.daemon;
20
21 import java.io.IOException;
22 import java.rmi.RemoteException;
23 import java.util.Iterator;
24
25 import jgroup.core.ConfigManager;
26 import jgroup.core.JgroupException;
27 import jgroup.core.MemberId;
28 import jgroup.core.registry.BootstrapRegistry;
29 import jgroup.relacs.config.DistributedSystemConfig;
30 import jgroup.relacs.config.Domain;
31 import jgroup.relacs.config.Host;
32 import jgroup.relacs.config.HostSet;
33 import jgroup.relacs.config.TransportConfig;
34 import jgroup.relacs.events.Event;
35 import jgroup.relacs.gm.RemoteDispatcher;
36 import jgroup.util.MsgFactory;
37 import jgroup.util.ThreadMonitor;
38
39 import org.apache.log4j.LogManager;
40 import org.apache.log4j.Logger;
41 import org.apache.log4j.MDC;
42
43
44
45
46
47
48
49
50
51
52 public class DaemonInteraction
53 {
54
55
56
57
58
59
60 private static final Logger log = Logger.getLogger(DaemonInteraction.class);
61
62
63
64
65
66
67
68
69
70
71 private static DaemonService daemonService;
72
73
74 private static TransportConfig tconf;
75
76
77
78
79
80
81
82
83
84
85
86
87 public static void initDaemon()
88 throws JgroupException
89 {
90
91 tconf = (TransportConfig) ConfigManager.getConfig(TransportConfig.class);
92
93
94 DistributedSystemConfig dsc = ConfigManager.getDistributedSystem();
95
96
97 MsgFactory.initMsgFactory(tconf.getPayload(), dsc.size(), dsc.numOfDomains());
98
99 Domain localDomain = DistributedSystemConfig.getLocalDomain();
100 if (localDomain.allDaemons()) {
101
102 init();
103
104 } else if (localDomain.hasNoDaemons()) {
105
106
107
108
109 throw new UnsupportedOperationException("The local domain must have at least one Jgroup daemon");
110
111 } else {
112
113 if (checkLocalDaemon() < 0) {
114 try {
115
116 daemonService = Daemon.lookupLocalDaemon();
117 if (log.isDebugEnabled()) {
118 log.debug("Daemon found in bootstrap registry");
119 }
120 } catch (JgroupException e) {
121
122 checkRemoteDaemons(localDomain);
123 }
124 }
125 }
126 }
127
128
129
130
131
132
133
134 private static int checkLocalDaemon()
135 {
136 if (daemonService == null)
137 daemonService = Daemon.quickLookupLocalDaemon();
138 if (daemonService != null) {
139 try {
140
141 return daemonService.members();
142 } catch (RemoteException e) {
143
144 }
145 }
146 return -1;
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 private static void checkRemoteDaemons(Domain domain)
165 throws JgroupException
166 {
167 HostSet hosts = domain.getHostSet();
168 int jdaemons = domain.numOfDaemons(), minMembers = Integer.MAX_VALUE;
169 for (Iterator iter = hosts.iterator(); jdaemons > 0 && iter.hasNext();) {
170 Host host = (Host) iter.next();
171 String dRegName = DaemonService.DAEMON_NAME + host.getPort();
172 try {
173 DaemonService jdService = (DaemonService) host.lookup(dRegName);
174
175
176 int members = jdService.members();
177
178 jdaemons--;
179
180
181
182
183
184 if (members < minMembers) {
185 daemonService = jdService;
186 minMembers = members;
187 }
188 if (log.isDebugEnabled()) {
189 log.debug("Found daemon on " + host);
190 log.debug("Members: " + members);
191 }
192
193 } catch (Exception e) {
194
195
196
197
198 }
199 }
200 if (jdaemons > 0) {
201 if (log.isDebugEnabled()) {
202 log.debug("remaining jdaemons to create: " + jdaemons);
203 log.debug("domain.jdaemons: " + domain.numOfDaemons());
204 }
205
206
207
208
209 init();
210
211 } else {
212
213
214
215
216 if (log.isDebugEnabled()) {
217 log.debug("Using: " + daemonService);
218 }
219
220 }
221 }
222
223
224
225
226
227 private static void init()
228 throws JgroupException
229 {
230 try {
231 BootstrapRegistry.refreshRegistryStub();
232 } catch (RemoteException e) {
233 throw new JgroupException("Could not initialize the bootstrap registry");
234 }
235
236
237 if (checkLocalDaemon() < 0) {
238 try {
239
240 daemonService = Daemon.createDaemon(tconf);
241 if (log.isDebugEnabled())
242 log.debug("Daemon created");
243 Daemon.bindLocalDaemon(daemonService);
244 } catch (IOException ioe) {
245 if (log.isDebugEnabled())
246 log.warn("Failed to create local Daemon", ioe);
247
248
249
250
251 daemonService = Daemon.lookupLocalDaemon();
252 if (log.isDebugEnabled())
253 log.debug("Daemon found in bootstrap registry");
254 }
255 }
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 public static MemberId getMemberId()
272 throws JgroupException
273 {
274 try {
275 return daemonService.getMemberId(DistributedSystemConfig.getLocalHost());
276 } catch (RemoteException e) {
277 throw new JgroupException("Unable to obtain my member identifier", e);
278 }
279 }
280
281
282
283
284
285
286
287
288
289 public static boolean addEvent(Event event)
290 {
291 try {
292 if (log.isDebugEnabled()) {
293 MDC.put("group", "[Group: " + event.getGid() + "]");
294 log.debug("Member->Daemon: " + event);
295 }
296 daemonService.addEvent(event);
297 if (log.isDebugEnabled())
298 log.debug("addEvent returned successfully (M->D)");
299 return true;
300 } catch (RemoteException e) {
301
302
303
304
305
306
307
308
309
310
311
312 log.warn("Member failed to send event to Daemon", e);
313 return handleDaemonFailure();
314 }
315 }
316
317
318
319
320
321
322
323
324
325
326
327
328
329 public static boolean addEvent(MemberData member, Event event)
330 {
331 try {
332 if (log.isDebugEnabled()) {
333 log.debug("Daemon->Member(" + member + "): " + event);
334 }
335 RemoteDispatcher dispatcher = member.getRemoteDispatcher();
336 synchronized (dispatcher) {
337 dispatcher.addEvent(event);
338 }
339 if (log.isDebugEnabled())
340 log.debug("addEvent returned successfully (D->M)");
341 return true;
342 } catch (RemoteException e) {
343
344
345
346
347
348
349
350
351
352 log.warn("Daemon failed to send event to " + member, e);
353 return false;
354 }
355 }
356
357
358
359
360
361
362
363
364
365
366
367
368 public static boolean handleDaemonFailure()
369 {
370 if (DaemonInteraction.suspectDaemon()) {
371
372
373
374
375
376 if (Boolean.getBoolean("jgroup.daemon.recover.locally")) {
377
378
379
380 if (log.isDebugEnabled())
381 log.debug("Trying to recover daemon locally");
382 try {
383 initDaemon();
384 return true;
385 } catch (JgroupException e) {
386 log.warn("Local daemon recovery failed.", e);
387 return false;
388 }
389 } else {
390
391
392
393
394
395 log.error("Crashing this member dispatcher since the daemon crashed");
396
397 LogManager.shutdown();
398 Runtime.getRuntime().halt(13);
399 return false;
400 }
401 } else {
402
403
404
405
406 log.error("DUMPING THREADS");
407 for (int i = 0; i < 10; i++) {
408 ThreadMonitor.dumpAllThreads();
409 try {
410 Thread.sleep(200);
411 } catch (InterruptedException e) { }
412 }
413 log.error("COMMITTING SUICIDE");
414 Runtime.getRuntime().halt(13);
415 return false;
416 }
417 }
418
419
420
421
422
423
424
425
426
427 public static boolean suspectDaemon()
428 {
429 assert daemonService != null : "DaemonService should not be null";
430 try {
431 int members = daemonService.members();
432 if (log.isDebugEnabled())
433 log.debug("Daemon is alive with members: "+ members);
434 return false;
435 } catch (RemoteException e1) {
436 if (log.isDebugEnabled()) {
437 log.debug("Daemon correctly suspected", e1);
438 }
439 return true;
440 }
441 }
442
443 }