All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgroups.demos.TotalOrder Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version


package org.jgroups.demos;

import org.jgroups.*;
import org.jgroups.util.Util;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.nio.ByteBuffer;


/**
 * Originally written to be a demo for TOTAL order (code to be written by a student). In the meantime,
 * it evolved into a state transfer demo. All members maintain a shared matrix and continually
 * broadcast changes to be applied to a randomly chosen field (e.g. multiplication of field with new
 * value, division, addition, subtraction). Each member can be started independently (starts to
 * broadcast update messages to all members). When "Stop" is pressed, a stop message is broadcast to
 * all members, causing them to stop sending messages. The "Clear" button clears the shared state;
 * "GetState" refreshes it from the shared group state (using the state transfer protocol).

If the * demo is to be used to show total order, then the SEQUENCER protocol would have to be added to the * stack. * * @author Bela Ban */ public class TotalOrder extends Frame { final Font def_font=new Font("Helvetica", Font.BOLD, 12); final Font def_font2=new Font("Helvetica", Font.PLAIN, 12); MyCanvas canvas; final MenuBar menubar=createMenuBar(); final Button start=new Button("Start"); final Button stop=new Button("Stop"); final Button clear=new Button("Clear"); final Button get_state=new Button("Get State"); final Button quit=new Button("Quit"); final Panel button_panel=new Panel(); SenderThread sender=null; JChannel channel; long timeout=0; int field_size=0; int num_fields=0; static final int x_offset=30; static final int y_offset=40; private int num=0; private int num_additions=0, num_subtractions=0, num_divisions=0, num_multiplications=0; static void error(String s) { System.err.println(s); } static class EventHandler extends WindowAdapter { final Frame gui; public EventHandler(Frame g) { gui=g; } public void windowClosing(WindowEvent e) { gui.dispose(); System.exit(0); } } class SenderThread extends Thread { TotOrderRequest req; boolean running=true; public void stopSender() { running=false; interrupt(); System.out.println("-- num_additions: " + num_additions + "\n-- num_subtractions: " + num_subtractions + "\n-- num_divisions: " + num_divisions + "\n-- num_multiplications: " + num_multiplications); num_additions=num_subtractions=num_multiplications=num_divisions=0; } public void run() { this.setName("SenderThread"); byte[] buf; int cnt=0; while(running) { try { req=createRandomRequest(); buf=req.toBuffer(); channel.send(new BytesMessage(null, buf)); System.out.print("-- num requests sent: " + cnt + "\r"); if(timeout > 0) Util.sleep(timeout); cnt++; if(num > 0 && cnt > num) { running=false; cnt=0; } } catch(Exception e) { error(e.toString()); return; } } } } void processRequest(TotOrderRequest req) throws Exception { int x=req.x, y=req.y, val=req.val; if(req.type == TotOrderRequest.STOP) { stopSender(); return; } switch(req.type) { case TotOrderRequest.ADDITION: canvas.addValueTo(x, y, val); num_additions++; break; case TotOrderRequest.SUBTRACTION: canvas.subtractValueFrom(x, y, val); num_subtractions++; break; case TotOrderRequest.MULTIPLICATION: canvas.multiplyValueWith(x, y, val); num_multiplications++; break; case TotOrderRequest.DIVISION: canvas.divideValueBy(x, y, val); num_divisions++; break; } canvas.update(); } public TotalOrder(String title, long timeout, int num_fields, int field_size, String props, int num) { Dimension s; this.timeout=timeout; this.num_fields=num_fields; this.field_size=field_size; this.num=num; setFont(def_font); start.addActionListener(e -> startSender()); stop.addActionListener(e -> { try { TotOrderRequest req=new TotOrderRequest(TotOrderRequest.STOP, 0, 0, 0); byte[] buf=req.toBuffer(); channel.send(new BytesMessage(null, buf)); } catch(Exception ex) { } }); clear.addActionListener(e -> canvas.clear()); get_state.addActionListener(e -> { try { channel.getState(null, 3000); } catch(Throwable t) { error("exception fetching state: " + t); } }); quit.addActionListener(e -> { channel.close(); System.exit(0); }); setTitle(title); addWindowListener(new EventHandler(this)); setBackground(Color.white); setMenuBar(menubar); setLayout(new BorderLayout()); canvas=new MyCanvas(num_fields, field_size, x_offset, y_offset); add("Center", canvas); button_panel.setLayout(new FlowLayout()); button_panel.setFont(def_font2); button_panel.add(start); button_panel.add(stop); button_panel.add(clear); button_panel.add(get_state); button_panel.add(quit); add("South", button_panel); s=canvas.getSize(); s.height+=100; setSize(s); try { channel=new JChannel(props); channel.setReceiver(new Receiver() { public void receive(Message msg) { try { TotOrderRequest req=new TotOrderRequest(); ByteBuffer buf=ByteBuffer.wrap(msg.getArray(), msg.getOffset(), msg.getLength()); req.init(buf); processRequest(req); } catch(Exception e) { System.err.println(e); } } public void getState(OutputStream output) throws Exception { int[][] copy_of_state=canvas.getCopyOfState(); Util.objectToStream(copy_of_state, new DataOutputStream(output)); } public void setState(InputStream input) throws Exception { canvas.setState(Util.objectFromStream(new DataInputStream(input))); } public void viewAccepted(View view) { System.out.println("view = " + view); } }); channel.connect("TotalOrderGroup"); channel.getState(null, 8000); } catch(Exception e) { e.printStackTrace(); System.exit(-1); } } void startSender() { if(sender == null || !sender.isAlive()) { sender=new SenderThread(); sender.start(); } } void stopSender() { if(sender != null) { sender.stopSender(); sender=null; } } private MenuBar createMenuBar() { MenuBar ret=new MenuBar(); Menu file=new Menu("File"); MenuItem quitm=new MenuItem("Quit"); ret.setFont(def_font2); ret.add(file); file.addSeparator(); file.add(quitm); quitm.addActionListener(e -> System.exit(1)); return ret; } private TotOrderRequest createRandomRequest() { TotOrderRequest ret=null; byte op_type=(byte)(((Math.random() * 10) % 4) + 1); // 1 - 4 int x=(int)((Math.random() * num_fields * 2) % num_fields); int y=(int)((Math.random() * num_fields * 2) % num_fields); int val=(int)((Math.random() * num_fields * 200) % 10); ret=new TotOrderRequest(op_type, x, y, val); return ret; } public static void main(String[] args) { TotalOrder g; String arg; long timeout=200; int num_fields=3; int field_size=80; String props=null; int num=0; props="udp.xml"; for(int i=0; i < args.length; i++) { arg=args[i]; if("-timeout".equals(arg)) { timeout=Long.parseLong(args[++i]); continue; } if("-num_fields".equals(arg)) { num_fields=Integer.parseInt(args[++i]); continue; } if("-field_size".equals(arg)) { field_size=Integer.parseInt(args[++i]); continue; } if("-help".equals(arg)) { help(); return; } if("-props".equals(arg)) { props=args[++i]; continue; } if("-num".equals(arg)) { num=Integer.parseInt(args[++i]); } help(); return; } try { g=new TotalOrder("Total Order Demo on " + InetAddress.getLocalHost().getHostName(), timeout, num_fields, field_size, props, num); g.setVisible(true); } catch(Exception e) { System.err.println(e); } } protected static void help() { System.out.println("\nTotalOrder [-timeout ] [-num_fields ] " + "[-field_size ] [-props ] [-num ]\n"); } } class TotOrderRequest { public static final byte STOP=0; public static final byte ADDITION=1; public static final byte SUBTRACTION=2; public static final byte MULTIPLICATION=3; public static final byte DIVISION=4; final static int SIZE=Global.BYTE_SIZE + Global.INT_SIZE * 3; public byte type=ADDITION; public int x=0; public int y=0; public int val=0; public TotOrderRequest() { } TotOrderRequest(byte type, int x, int y, int val) { this.type=type; this.x=x; this.y=y; this.val=val; } public String printType() { switch(type) { case STOP: return "STOP"; case ADDITION: return "ADDITION"; case SUBTRACTION: return "SUBTRACTION"; case MULTIPLICATION: return "MULTIPLICATION"; case DIVISION: return "DIVISION"; default: return ""; } } // public void writeExternal(ObjectOutput out) throws IOException { // out.writeByte(type); // out.writeInt(x); // out.writeInt(y); // out.writeInt(val); // } // // public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { // type=in.readByte(); // x=in.readInt(); // y=in.readInt(); // val=in.readInt(); // } public byte[] toBuffer() { ByteBuffer buf=ByteBuffer.allocate(SIZE); buf.put(type); buf.putInt(x); buf.putInt(y); buf.putInt(val); return buf.array(); } public void init(ByteBuffer buf) { type=buf.get(); x=buf.getInt(); y=buf.getInt(); val=buf.getInt(); } public String toString() { return "[" + x + ',' + y + ": " + printType() + '(' + val + ")]"; } } class MyCanvas extends Canvas { int field_size=100; int num_fields=4; int x_offset=30; int y_offset=30; final Font def_font=new Font("Helvetica", Font.BOLD, 14); final int[][] array; // state Dimension off_dimension=null; Image off_image=null; Graphics off_graphics=null; final Font def_font2=new Font("Helvetica", Font.PLAIN, 12); static final Color checksum_col=Color.blue; int checksum=0; public MyCanvas(int num_fields, int field_size, int x_offset, int y_offset) { this.num_fields=num_fields; this.field_size=field_size; this.x_offset=x_offset; this.y_offset=y_offset; array=new int[num_fields][num_fields]; setBackground(Color.white); setSize(2 * x_offset + num_fields * field_size + 30, y_offset + num_fields * field_size + 50); for(int i=0; i < num_fields; i++) for(int j=0; j < num_fields; j++) array[i][j]=0; } public void setFieldSize(int fs) { field_size=fs; } public void setNumFields(int nf) { num_fields=nf; } public void setXOffset(int o) { x_offset=o; } public void setYOffset(int o) { y_offset=o; } public void addValueTo(int x, int y, int value) { synchronized(array) { array[x][y]+=value; repaint(); } } public void subtractValueFrom(int x, int y, int value) { synchronized(array) { array[x][y]-=value; repaint(); } } public void multiplyValueWith(int x, int y, int value) { synchronized(array) { array[x][y]*=value; repaint(); } } public void divideValueBy(int x, int y, int value) { if(value == 0) return; synchronized(array) { array[x][y]/=value; repaint(); } } public void setValueAt(int x, int y, int value) { synchronized(array) { array[x][y]=value; } repaint(); } public int getValueAt(int x, int y) { synchronized(array) { return array[x][y]; } } public void clear() { synchronized(array) { for(int i=0; i < num_fields; i++) for(int j=0; j < num_fields; j++) array[i][j]=0; checksum=checksum(); repaint(); } } public int[][] getState() { synchronized(array) { return array; } } public int[][] getCopyOfState() { int[][] retval=new int[num_fields][num_fields]; synchronized(array) { for(int i=0; i < num_fields; i++) System.arraycopy(array[i], 0, retval[i], 0, num_fields); return retval; } } public void update() { checksum=checksum(); repaint(); } public void setState(Object new_state) { if(new_state == null) return; try { int[][] new_array=(int[][])new_state; synchronized(array) { clear(); for(int i=0; i < num_fields; i++) System.arraycopy(new_array[i], 0, array[i], 0, num_fields); checksum=checksum(); repaint(); } } catch(Exception e) { System.err.println(e); } } public int checksum() { int retval=0; synchronized(array) { for(int i=0; i < num_fields; i++) for(int j=0; j < num_fields; j++) retval+=array[i][j]; } return retval; } public void update(Graphics g) { Dimension d=getSize(); if(off_graphics == null || d.width != off_dimension.width || d.height != off_dimension.height) { off_dimension=d; off_image=createImage(d.width, d.height); off_graphics=off_image.getGraphics(); } //Erase the previous image. off_graphics.setColor(getBackground()); off_graphics.fillRect(0, 0, d.width, d.height); off_graphics.setColor(Color.black); off_graphics.setFont(def_font); drawEmptyBoard(off_graphics); drawNumbers(off_graphics); g.drawImage(off_image, 0, 0, this); } public void paint(Graphics g) { update(g); } /** * Draws the empty board, no pieces on it yet, just grid lines */ void drawEmptyBoard(Graphics g) { int x=x_offset, y=y_offset; Color old_col=g.getColor(); g.setFont(def_font2); old_col=g.getColor(); g.setColor(checksum_col); g.drawString(("Checksum: " + checksum), x_offset + field_size, y_offset - 20); g.setFont(def_font); g.setColor(old_col); for(int i=0; i < num_fields; i++) { for(int j=0; j < num_fields; j++) { // draws 1 row g.drawRect(x, y, field_size, field_size); x+=field_size; } g.drawString((String.valueOf((num_fields - i - 1))), x + 20, y + field_size / 2); y+=field_size; x=x_offset; } for(int i=0; i < num_fields; i++) { g.drawString((String.valueOf(i)), x_offset + i * field_size + field_size / 2, y + 30); } } void drawNumbers(Graphics g) { Point p; String num; FontMetrics fm=g.getFontMetrics(); int len=0; synchronized(array) { for(int i=0; i < num_fields; i++) for(int j=0; j < num_fields; j++) { num=String.valueOf(array[i][j]); len=fm.stringWidth(num); p=index2Coord(i, j); g.drawString(num, p.x - (len / 2), p.y); } } } Point coord2Index(int x, int y) { Point ret=new Point(); ret.x=x_offset + (x * field_size); ret.y=y_offset + ((num_fields - 1 - y) * field_size); return ret; } Point index2Coord(int i, int j) { int x=x_offset + i * field_size + field_size / 2; int y=y_offset + num_fields * field_size - j * field_size - field_size / 2; return new Point(x, y); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy