KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > demos > TotalOrder


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

3
4 package org.jgroups.demos;
5
6 import org.jgroups.*;
7 import org.jgroups.util.Util;
8
9 import java.awt.*;
10 import java.awt.event.ActionEvent JavaDoc;
11 import java.awt.event.ActionListener JavaDoc;
12 import java.awt.event.WindowAdapter JavaDoc;
13 import java.awt.event.WindowEvent JavaDoc;
14 import java.net.InetAddress JavaDoc;
15
16
17
18
19 /**
20  * Originally written to be a demo for TOTAL order (code to be written by a student). In the meantime,
21  * it evolved into a state transfer demo. All members maintain a shared matrix and continually
22  * broadcast changes to be applied to a randomly chosen field (e.g. multiplication of field with new
23  * value, division, addition, subtraction). Each member can be started independently (starts to
24  * broadcast update messages to all members). When "Stop" is pressed, a stop message is broadcast to
25  * all members, causing them to stop sending messages. The "Clear" button clears the shared state;
26  * "GetState" refreshes it from the shared group state (using the state transfer protocol).<p>If the
27  * demo is to be used to show TOTAL order, then the TOTAL protocol would have to be added to the
28  * stack.
29  * @author Bela Ban
30  */

31 public class TotalOrder extends Frame {
32     final Font def_font=new Font("Helvetica", Font.BOLD, 12);
33     final Font def_font2=new Font("Helvetica", Font.PLAIN, 12);
34     MyCanvas canvas;
35     final MenuBar menubar=createMenuBar();
36     final Button start=new Button("Start");
37     final Button stop=new Button("Stop");
38     final Button clear=new Button("Clear");
39     final Button get_state=new Button("Get State");
40     final Button quit=new Button("Quit");
41     final Panel button_panel=new Panel();
42     SenderThread sender=null;
43     ReceiverThread receiver=null;
44     Channel channel;
45     Dialog error_dlg;
46     long timeout=0;
47     int field_size=0;
48     int num_fields=0;
49     static final int x_offset=30;
50     static final int y_offset=40;
51
52
53
54     void error(String JavaDoc s) {
55     System.err.println(s);
56     }
57
58
59
60     class EventHandler extends WindowAdapter JavaDoc {
61     final Frame gui;
62
63     public EventHandler(Frame g) {gui=g;}
64
65     public void windowClosing(WindowEvent JavaDoc e) {
66         gui.dispose();
67         System.exit(0);
68     }
69     }
70
71
72
73
74     class SenderThread extends Thread JavaDoc {
75     TotOrderRequest req;
76     boolean running=true;
77
78     public void stopSender() {
79         running=false;
80         interrupt();
81     }
82
83     public void run() {
84         this.setName("SenderThread");
85
86         while(running) {
87         try {
88             req=createRandomRequest();
89             channel.send(new Message(null, null, Util.objectToByteBuffer(req)));
90             Util.sleep(timeout);
91         }
92         catch(Exception JavaDoc e) {
93             error(e.toString());
94             return;
95         }
96         }
97     }
98     }
99
100
101     class ReceiverThread extends Thread JavaDoc {
102     Object JavaDoc o;
103     Message msg;
104     TotOrderRequest req;
105     SetStateEvent set_state_evt;
106     boolean running=true;
107
108
109     public void stopReceiver() {
110         running=false;
111         interrupt();
112     }
113
114     public void run() {
115         this.setName("ReceiverThread");
116         while(running) {
117         try {
118             o=channel.receive(0);
119             if(o instanceof Message) {
120             try {
121                 msg=(Message)o;
122
123                 Object JavaDoc tmp=msg.getObject();
124
125                 if(!(tmp instanceof TotOrderRequest)) {
126                 System.err.println("tmp is " + tmp.getClass() + ": " + tmp);
127                 if(tmp instanceof Message) {
128                     System.out.print("Hdrs are ");
129                     ((Message)tmp).printObjectHeaders();
130                 }
131
132                 }
133
134
135                 req=(TotOrderRequest)tmp;
136                 processRequest(req);
137             }
138             catch(Exception JavaDoc e) {
139                 System.err.println(e);
140             }
141             }
142             else if(o instanceof GetStateEvent) {
143             int[][] copy_of_state=canvas.getCopyOfState();
144             channel.returnState(Util.objectToByteBuffer(copy_of_state));
145             }
146             else if(o instanceof SetStateEvent) { // state was received, set it !
147
set_state_evt=(SetStateEvent)o;
148             canvas.setState(Util.objectFromByteBuffer(set_state_evt.getArg()));
149             } else if (o instanceof View) System.out.println(o.toString());
150         }
151         catch(ChannelClosedException closed) {
152             error("Channel has been closed; receiver thread quits");
153             return;
154         }
155         catch(Exception JavaDoc e) {
156             error(e.toString());
157             return;
158         }
159         }
160     }
161     }
162
163
164
165     void processRequest(TotOrderRequest req) throws Exception JavaDoc {
166     int x=req.x, y=req.y, val=req.val, result=0;
167
168     if(req.type == TotOrderRequest.STOP) {
169         stopSender();
170         return;
171     }
172
173     switch(req.type) {
174     case TotOrderRequest.ADDITION:
175         result=canvas.addValueTo(x, y, val);
176         break;
177     case TotOrderRequest.SUBTRACTION:
178         result=canvas.subtractValueFrom(x, y, val);
179         break;
180     case TotOrderRequest.MULTIPLICATION:
181         result=canvas.multiplyValueWith(x, y, val);
182         break;
183     case TotOrderRequest.DIVISION:
184         result=canvas.divideValueBy(x, y, val);
185         break;
186     }
187     canvas.update();
188     }
189
190
191
192     public TotalOrder(String JavaDoc title, long timeout, int num_fields, int field_size, String JavaDoc props) {
193         Dimension s;
194
195         this.timeout = timeout;
196         this.num_fields = num_fields;
197         this.field_size = field_size;
198         setFont(def_font);
199
200         try {
201             channel = new JChannel(props);
202             channel.setOpt(Channel.GET_STATE_EVENTS, Boolean.TRUE);
203             channel.connect("TotalOrderGroup");
204             boolean rc = channel.getState(null, 8000);
205         }
206         catch (Exception JavaDoc e) {
207             error(e.toString());
208             System.exit(-1);
209         }
210
211         start.addActionListener(new ActionListener JavaDoc() {
212             public void actionPerformed(ActionEvent JavaDoc e) {
213                 startSender();
214             }
215         });
216
217         stop.addActionListener(new ActionListener JavaDoc() {
218             public void actionPerformed(ActionEvent JavaDoc e) {
219                 try {
220                     channel.send(
221                         new Message(
222                             null,
223                             null,
224                             Util.objectToByteBuffer(new TotOrderRequest(TotOrderRequest.STOP, 0, 0, 0))));
225                 }
226                 catch (Exception JavaDoc ex) {
227                 }
228
229             }
230         });
231
232         clear.addActionListener(new ActionListener JavaDoc() {
233             public void actionPerformed(ActionEvent JavaDoc e) {
234                 canvas.clear();
235             }
236         });
237
238         get_state.addActionListener(new ActionListener JavaDoc() {
239             public void actionPerformed(ActionEvent JavaDoc e) {
240                 try {
241                     boolean rc = channel.getState(null, 3000);
242                     if (rc == false)
243                         error("State could not be retrieved !");
244                 }
245                 catch(Throwable JavaDoc t) {
246                     error("exception fetching state: " + t);
247                 }
248             }
249         });
250
251         quit.addActionListener(new ActionListener JavaDoc() {
252             public void actionPerformed(ActionEvent JavaDoc e) {
253                 channel.disconnect();
254                 channel.close();
255                 System.exit(0);
256             }
257         });
258
259         setTitle(title);
260         addWindowListener(new EventHandler(this));
261         setBackground(Color.white);
262         setMenuBar(menubar);
263
264         setLayout(new BorderLayout());
265         canvas = new MyCanvas(num_fields, field_size, x_offset, y_offset);
266
267         add("Center", canvas);
268         button_panel.setLayout(new FlowLayout());
269         button_panel.setFont(def_font2);
270         button_panel.add(start);
271         button_panel.add(stop);
272         button_panel.add(clear);
273         button_panel.add(get_state);
274         button_panel.add(quit);
275         add("South", button_panel);
276
277         s = canvas.getSize();
278         s.height += 100;
279         setSize(s);
280         startReceiver();
281     }
282
283
284     void startSender() {
285     if(sender == null) {
286         sender=new SenderThread();
287         sender.start();
288     }
289     }
290
291     void stopSender() {
292     if(sender != null) {
293         sender.stopSender();
294         sender=null;
295     }
296     }
297
298     void startReceiver() {
299     if(receiver == null) {
300         receiver=new ReceiverThread();
301         receiver.setPriority(Thread.MAX_PRIORITY);
302         receiver.start();
303     }
304     }
305
306     void stopReceiver() {
307     if(receiver != null) {
308         receiver.stopReceiver();
309         receiver=null;
310     }
311     }
312
313
314
315     MenuBar createMenuBar() {
316     MenuBar ret=new MenuBar();
317     Menu file=new Menu("File");
318     MenuItem quit=new MenuItem("Quit");
319
320     ret.setFont(def_font2);
321     ret.add(file);
322
323     file.addSeparator();
324     file.add(quit);
325
326
327     quit.addActionListener(
328                    new ActionListener JavaDoc() {
329         public void actionPerformed(ActionEvent JavaDoc e) {
330         System.exit(1);
331         }});
332     return ret;
333     }
334
335
336     public void rrror(String JavaDoc msg) {
337     Button ok=new Button("Ok");
338     Label l=new Label(msg);
339
340     error_dlg=new Dialog(this, msg, true);
341     error_dlg.setLocation(90, 150);
342     error_dlg.setSize(420, 100);
343     error_dlg.setLayout(new BorderLayout());
344     error_dlg.setFont(def_font2);
345
346     ok.addActionListener(new ActionListener JavaDoc() {
347         public void actionPerformed(ActionEvent JavaDoc e) {
348         error_dlg.dispose();
349         }
350     });
351
352     error_dlg.add("Center", l);
353     error_dlg.add("South", ok);
354     error_dlg.show();
355     }
356
357
358
359     TotOrderRequest createRandomRequest() {
360     TotOrderRequest ret=null;
361     int op_type=(int)(((Math.random() * 10) % 4)+1); // 1 - 4
362
int x=(int)((Math.random() * num_fields * 2) % num_fields);
363     int y=(int)((Math.random() * num_fields * 2) % num_fields);
364     int val=(int)((Math.random() * num_fields * 200) % 10);
365
366     ret=new TotOrderRequest(op_type, x, y, val);
367     return ret;
368     }
369
370
371
372
373     public static void main(String JavaDoc[] args) {
374     TotalOrder g;
375     String JavaDoc arg;
376     long timeout=200;
377     int num_fields=3;
378     int field_size=80;
379     String JavaDoc props=null;
380
381     props="UDP(mcast_addr=224.0.0.35;mcast_port=45566;ip_ttl=0;" +
382         "mcast_send_buf_size=150000;mcast_recv_buf_size=80000):" +
383         "PING(timeout=2000;num_initial_members=3):" +
384         "MERGE2(min_interval=5000;max_interval=10000):" +
385         "FD_SOCK:" +
386         "VERIFY_SUSPECT(timeout=1500):" +
387         "pbcast.STABLE(desired_avg_gossip=20000):" +
388         "pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800):" +
389         "UNICAST(timeout=5000):" +
390         "FRAG(frag_size=4096;down_thread=false;up_thread=false):" +
391         "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;" +
392         "shun=false;print_local_addr=true):" +
393         "pbcast.STATE_TRANSFER";
394     
395     
396
397     for(int i=0; i < args.length; i++) {
398         arg=args[i];
399         if("-timeout".equals(arg)) {
400         timeout=Long.parseLong(args[++i]);
401         continue;
402         }
403         if("-num_fields".equals(arg)) {
404         num_fields=Integer.parseInt(args[++i]);
405         continue;
406         }
407         if("-field_size".equals(arg)) {
408         field_size=Integer.parseInt(args[++i]);
409         continue;
410         }
411         if("-help".equals(arg)) {
412         System.out.println("\nTotalOrder [-timeout <value>] [-num_fields <value>] "+
413                    "[-field_size <value>] [-props <properties (can be URL)>]\n");
414         return;
415         }
416         if("-props".equals(arg)) {
417         props=args[++i];
418         continue;
419         }
420     }
421
422
423     try {
424         g=new TotalOrder("Total Order Demo on " + InetAddress.getLocalHost().getHostName(),
425                  timeout, num_fields, field_size, props);
426         g.show();
427     }
428     catch(Exception JavaDoc e) {
429         System.err.println(e);
430     }
431     }
432
433
434
435 }
436
437
438
439
440 class TotOrderRequest implements java.io.Serializable JavaDoc {
441     public static final int STOP = 0;
442     public static final int ADDITION = 1;
443     public static final int SUBTRACTION = 2;
444     public static final int MULTIPLICATION = 3;
445     public static final int DIVISION = 4;
446
447
448     public int type=ADDITION;
449     public int x=0;
450     public int y=0;
451     public int val=0;
452
453
454     TotOrderRequest(int type, int x, int y, int val) {
455     this.type=type; this.x=x; this.y=y; this.val=val;
456     }
457
458     public static String JavaDoc type2Str(int t) {
459     switch(t) {
460     case STOP: return "STOP";
461     case ADDITION: return "ADDITION";
462     case SUBTRACTION: return "SUBTRACTION";
463     case MULTIPLICATION: return "MULTIPLICATION";
464     case DIVISION: return "DIVISION";
465     default: return "<unknown>";
466     }
467     }
468
469     public String JavaDoc toString() {
470     return "[" + x + ',' + y + ": " + type2Str(type) + '(' + val + ")]";
471     }
472 }
473
474
475
476 class MyCanvas extends Canvas {
477     int field_size=100;
478     int num_fields=4;
479     int x_offset=30;
480     int y_offset=30;
481
482     final Font def_font=new Font("Helvetica", Font.BOLD, 14);
483     int[][] array=null; // state
484

485     Dimension off_dimension=null;
486     Image off_image=null;
487     Graphics off_graphics=null;
488     final Font def_font2=new Font("Helvetica", Font.PLAIN, 12);
489     static final Color checksum_col=Color.blue;
490     int checksum=0;
491
492
493     public MyCanvas(int num_fields, int field_size, int x_offset, int y_offset) {
494     this.num_fields=num_fields; this.field_size=field_size;
495     this.x_offset=x_offset; this.y_offset=y_offset;
496
497     array=new int[num_fields][num_fields];
498     setBackground(Color.white);
499     setSize(2*x_offset + num_fields*field_size+30, y_offset + num_fields*field_size+50);
500
501     for(int i=0; i < num_fields; i++)
502         for(int j=0; j < num_fields; j++)
503         array[i][j]=0;
504     }
505
506
507     public void setFieldSize(int fs) {field_size=fs;}
508     public void setNumFields(int nf) {num_fields=nf;}
509     public void setXOffset(int o) {x_offset=o;}
510     public void setYOffset(int o) {y_offset=o;}
511
512
513     public int addValueTo(int x, int y, int value) {
514     synchronized(array) {
515         array[x][y]+=value;
516         repaint();
517         return array[x][y];
518     }
519     }
520
521     public int subtractValueFrom(int x, int y, int value) {
522     synchronized(array) {
523         array[x][y]-=value;
524         repaint();
525         return array[x][y];
526     }
527     }
528
529     public int multiplyValueWith(int x, int y, int value) {
530     synchronized(array) {
531         array[x][y]*=value;
532         repaint();
533         return array[x][y];
534     }
535     }
536
537     public int divideValueBy(int x, int y, int value) {
538     if(value == 0)
539         return array[x][y];
540     synchronized(array) {
541         array[x][y]/=value;
542         repaint();
543         return array[x][y];
544     }
545     }
546
547
548     public void setValueAt(int x, int y, int value) {
549     synchronized(array) {
550         array[x][y]=value;
551     }
552     repaint();
553     }
554
555
556
557     public int getValueAt(int x, int y) {
558     synchronized(array) {
559         return array[x][y];
560     }
561     }
562
563
564     public void clear() {
565     synchronized(array) {
566         for(int i=0; i < num_fields; i++)
567         for(int j=0; j < num_fields; j++)
568             array[i][j]=0;
569         checksum=checksum();
570         repaint();
571     }
572     }
573
574
575     public int[][] getState() {
576     synchronized(array) {
577         return array;
578     }
579     }
580
581
582     public int[][] getCopyOfState() {
583     int[][] retval=new int[num_fields][num_fields];
584
585     synchronized(array) {
586         for(int i=0; i < num_fields; i++)
587             System.arraycopy(array[i], 0, retval[i], 0, num_fields);
588         return retval;
589     }
590     }
591
592
593     public void update() {
594     checksum=checksum();
595     repaint();
596     }
597
598
599     public void setState(Object JavaDoc new_state) {
600
601     if(new_state == null)
602         return;
603
604     try {
605         int[][] new_array=(int[][])new_state;
606         synchronized(array) {
607         clear();
608
609         for(int i=0; i < num_fields; i++)
610             System.arraycopy(new_array[i], 0, array[i], 0, num_fields);
611         checksum=checksum();
612         repaint();
613         }
614     }
615     catch(Exception JavaDoc e) {
616         System.err.println(e);
617         return;
618     }
619     }
620
621
622     public int checksum() {
623     int retval=0;
624
625     synchronized(array) {
626         for(int i=0; i < num_fields; i++)
627         for(int j=0; j < num_fields; j++)
628             retval+=array[i][j];
629     }
630     return retval;
631     }
632
633
634
635     public void update(Graphics g) {
636     Dimension d=getSize();
637
638     if(off_graphics == null ||
639        d.width != off_dimension.width ||
640        d.height != off_dimension.height) {
641         off_dimension=d;
642         off_image=createImage(d.width, d.height);
643         off_graphics=off_image.getGraphics();
644     }
645
646     //Erase the previous image.
647
off_graphics.setColor(getBackground());
648     off_graphics.fillRect(0, 0, d.width, d.height);
649     off_graphics.setColor(Color.black);
650     off_graphics.setFont(def_font);
651     drawEmptyBoard(off_graphics);
652     drawNumbers(off_graphics);
653     g.drawImage(off_image, 0, 0, this);
654     }
655
656
657
658
659     public void paint(Graphics g) {
660     update(g);
661     }
662
663
664
665
666     /** Draws the empty board, no pieces on it yet, just grid lines */
667     void drawEmptyBoard(Graphics g) {
668     int x=x_offset, y=y_offset;
669     Color old_col=g.getColor();
670
671     g.setFont(def_font2);
672     old_col=g.getColor();
673     g.setColor(checksum_col);
674     g.drawString(("Checksum: " + checksum), x_offset + field_size, y_offset - 20);
675     g.setFont(def_font);
676     g.setColor(old_col);
677
678     for(int i=0; i < num_fields; i++) {
679         for(int j=0; j < num_fields; j++) { // draws 1 row
680
g.drawRect(x, y, field_size, field_size);
681         x+=field_size;
682         }
683         g.drawString(("" + (num_fields-i-1)), x+20, y+field_size/2);
684         y+=field_size;
685         x=x_offset;
686     }
687
688     for(int i=0; i < num_fields; i++) {
689         g.drawString((""+i), x_offset + i*field_size + field_size/2, y+30);
690     }
691     }
692
693
694
695     void drawNumbers(Graphics g) {
696     Point p;
697     String JavaDoc num;
698     FontMetrics fm=g.getFontMetrics();
699     int len=0;
700
701     synchronized(array) {
702         for(int i=0; i < num_fields; i++)
703         for(int j=0; j < num_fields; j++) {
704             num="" + array[i][j];
705             len=fm.stringWidth(num);
706             p=index2Coord(i, j);
707             g.drawString(num, p.x - (len/2), p.y);
708         }
709     }
710     }
711
712
713
714
715     Point coord2Index(int x, int y) {
716     Point ret=new Point();
717
718     ret.x=x_offset + (x * field_size);
719     ret.y=y_offset + ((num_fields - 1 - y) * field_size);
720     return ret;
721     }
722
723
724     Point index2Coord(int i, int j) {
725     int x=x_offset + i*field_size + field_size/2;
726
727     // int y=y_offset + j*field_size + field_size/2;
728

729     int y=y_offset + num_fields*field_size - j*field_size - field_size/2;
730
731     return new Point(x, y);
732     }
733
734
735 }
736
737
738
739
740
741
742
743
744
Popular Tags