Home | Papers | Reports | Projects | Code Fragments | Dissertations | Presentations | Posters | Proposals | Lectures given | Course notes |
<< 13. Petrinet Design of a Whiteboard Voting System | 15. Various Cases of Peer-to-peer distributed systems >> |
14. Behavioral ReplicationWerner Van Belle1 - werner@yellowcouch.org, werner.van.belle@gmail.com Abstract : In this exercise we try to duplicate one calculation and present it transparently to the client. The aim being to create a robust fault tolerant system. This exercise was used in 2002-2003
Reference:
Werner Van Belle; Behavioral Replication; |
import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.rmi.*; import java.rmi.server.*; public class Adder extends Actor { public Adder(String name, String args[]) throws RemoteException { super(name); } public void handleMessage(Message m) { AddRequest req = (AddRequest)m; sendMessage(req.comesfrom, new AddAnswer(actor,req.a+req.b)); } public static void main(String args[]) { try { new Adder(args[0],args); } catch (Exception e) { System.out.println(e); e.printStackTrace(); } } }
public class AddRequest implements Message { int a,b; String comesfrom; public AddRequest(String comes, int A, int B) { comesfrom = comes; a=A; b=B; } }
public class AddAnswer implements Message { int result; String comesfrom; public AddAnswer(String from, int r) { comesfrom = from; result = r; } }
import java.awt.*; import java.rmi.*; import java.rmi.server.*; import java.util.Random; public class Client extends Actor { // location of adder process String adder; // the two number that should be added int a; int b; Random random; public Client(String name, String args[]) throws RemoteException { super(name); adder=args[1]; random=new Random(); System.out.println("Client "+actor+" started"); sendNumbers(); } public void sendNumbers() { a=random.nextInt(); b=random.nextInt(); // 'actor' is the name of this process sendMessage(adder,new AddRequest(actor,a,b)); } public void handleMessage(Message m) { AddAnswer answer = (AddAnswer)m; System.out.println(actor+" addition of "+a+" and "+b+" is "+answer.result); if (answer.result!=a+b) System.out.println("\n>>>>>>>>>>> This is wrong ! <<<<<<<<<<<<<<<<<<\n\n\n"); else sendNumbers(); } public static void main(String args[]) { try { new Client(args[0],args); } catch (Exception e) { System.out.println(e); e.printStackTrace(); } } }
#!/bin/bash rmiregistry & java Adder //127.0.0.1/Adder & java Client //127.0.0.1/Client1 //127.0.0.1/Adder &
#!/bin/bash echo STARTING REGISTRY rmiregistry 2>/dev/null & sleep 5 echo STARTING PROXY java Proxy //7.0.0.1/Adder 2>proxy_log & sleep 5 echo STARTING FIRST ADDER java ModifiedAdder //7.0.0.1/Adder1 //7.0.0.1/Adder 2>/dev/null & sleep 5; echo STARTING FIRST CLIENT java Client //7.0.0.1/Client1 //7.0.0.1/Adder 2>/dev/null & sleep 5 echo STARTING SECOND ADDER java ModifiedAdder //7.0.0.1/Adder2 //7.0.0.1/Adder 2>/dev/null & sleep 5 echo STARTING THIRD ADDER java ModifiedAdder //7.0.0.1/Adder3 //7.0.0.1/Adder 2>/dev/null & sleep 5 echo STARTING SECOND CLIENT java Client //7.0.0.1/Client2 //7.0.0.1/Adder 2>/dev/null & sleep 5 echo STARTING FOURTH/FIFTH/SIXTH AND SEVENTH ADDER java ModifiedAdder //7.0.0.1/Adder4 //7.0.0.1/Adder 2>/dev/null & java ModifiedAdder //7.0.0.1/Adder5 //7.0.0.1/Adder 2>/dev/null & java ModifiedAdder //7.0.0.1/Adder6 //7.0.0.1/Adder 2>/dev/null & java ModifiedAdder //7.0.0.1/Adder7 //7.0.0.1/Adder 2>/dev/null & sleep 5 echo STARTING THIRD/FOURTH/FIFTH CLIENT java Client //7.0.0.1/Client3 //7.0.0.1/Adder 2>/dev/null & java Client //7.0.0.1/Client4 //7.0.0.1/Adder 2>/dev/null & java Client //7.0.0.1/Client5 //7.0.0.1/Adder 2>/dev/null & echo ALL STARTED !!!
public class ConnectionRequest implements Message { String name; public ConnectionRequest(String comes) { name = comes; } }
import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.rmi.*; import java.rmi.server.*; import java.util.*; public class ModifiedAdder extends Actor { String proxy; public ModifiedAdder(String name, String args[]) throws RemoteException { super(name); proxy=args[1]; sendMessage(proxy,new ConnectionRequest(actor)); } public void handleMessage(Message m) { AddRequest req = (AddRequest)m; // System.out.println("Adder "+actor+" activated"); sendMessage(req.comesfrom, new AddAnswer(actor, req.a+req.b)); } public static void main(String args[]) { try { new ModifiedAdder(args[0],args); } catch (Exception e) { System.out.println(e); e.printStackTrace(); } } }
import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.rmi.*; import java.rmi.server.*; import java.util.*; class MessageInfo { AddRequest req; HashMap client_answer; public MessageInfo(AddRequest r) { req = r; client_answer = new HashMap(); } public int answer() { Iterator it = client_answer.values().iterator(); while(it.hasNext()) { AddAnswer answer = (AddAnswer)it.next(); return answer.result; } return -1; } public boolean fullAnswer() { Iterator it = client_answer.values().iterator(); while(it.hasNext()) { if (it.next()==null) return false; } return true; } public void sentTo(String client) { client_answer.put(client,null); } public boolean acceptAnswer(AddAnswer answer) { String client = answer.comesfrom; if (!client_answer.containsKey(client)) return false; if (client_answer.get(client)!=null) return false; client_answer.put(client,answer); return true; } } public class Proxy extends Actor { LinkedList queue; Vector connectedClients; public Proxy(String name, String args[]) throws RemoteException { super(name); queue=new LinkedList(); connectedClients = new Vector(); } private void sendToAllClients(AddRequest req) { if (connectedClients.isEmpty()) { System.out.println("Sorry, can't do, no active clients"); System.exit(0); } MessageInfo info = new MessageInfo(req); queue.addLast(info); Iterator it = connectedClients.iterator(); while(it.hasNext()) { String client = (String)it.next(); sendMessage(client,new AddRequest(actor,req.a,req.b)); info.sentTo(client); } } private void flushLoop() { // find out which messages have a full answer // which messages needs to be resend Iterator it = queue.iterator(); // System.out.println(" queue size = "+queue.size()); while (it.hasNext()) { MessageInfo info = (MessageInfo)it.next(); if (info.fullAnswer()) { it.remove(); sendMessage(info.req.comesfrom, new AddAnswer(actor,info.answer())); } } } public void handleMessage(Message m) { if (m instanceof ConnectionRequest) { ConnectionRequest cr=(ConnectionRequest)m; connectedClients.add(cr.name); System.out.println("Proxy has new adder "+cr.name); } else if (m instanceof AddRequest) { AddRequest req = (AddRequest)m; // send through the request sendToAllClients(req); } else if (m instanceof AddAnswer) { AddAnswer answer = (AddAnswer)m; Iterator it = queue.iterator(); // now we store the answer in the earliest sent message while(it.hasNext()) { MessageInfo info = (MessageInfo)it.next(); if (info.acceptAnswer(answer)) break; } // mark the adder which is still alive flushLoop(); } else super.handleMessage(m); } public static void main(String args[]) { try { new Proxy(args[0],args); } catch (Exception e) { System.out.println(e); e.printStackTrace(); } } }
http://werner.yellowcouch.org/ werner@yellowcouch.org |