package org.jgroups.tests; import org.jgroups.Address; import org.jgroups.Message; import org.jgroups.stack.NakReceiverWindow; import org.jgroups.stack.Retransmitter; import org.jgroups.util.DefaultTimeScheduler; import org.jgroups.util.TimeScheduler; import org.jgroups.util.Util; import java.io.IOException; /** * Adds a large number of messages (with gaps to simulate message loss) into NakReceiverWindow. Receives messages * on another thread. When the receiver thread has received all messages it prints out the time taken and terminates. * * @author Bela Ban */ public class NakReceiverWindowStressTest implements Retransmitter.RetransmitCommand { NakReceiverWindow win=null; final Address sender=Util.createRandomAddress("A"); int num_msgs=1000, prev_value=0; double discard_prob=0.0; // discard 0% of all insertions long start, stop; boolean trace=false; boolean debug=false; public NakReceiverWindowStressTest(int num_msgs, double discard_prob, boolean trace) { this.num_msgs=num_msgs; this.discard_prob=discard_prob; this.trace=trace; } public void retransmit(long first_seqno, long last_seqno, Address sender) { for(long i=first_seqno; i <= last_seqno; i++) { if(debug) out("-- xmit: " + i); Message m=new Message(null, sender, new Long(i)); win.add(i, m); } } public void start() throws IOException, InterruptedException { System.out.println("num_msgs=" + num_msgs + "\ndiscard_prob=" + discard_prob); TimeScheduler timer=new DefaultTimeScheduler(); try { win=new NakReceiverWindow(sender, this, 0, timer); start=System.currentTimeMillis(); sendMessages(num_msgs); } finally { timer.stop(); } } void sendMessages(int num_msgs) { Message msg; for(long i=1; i <= num_msgs; i++) { if(discard_prob > 0 && Util.tossWeightedCoin(discard_prob) && i <= num_msgs) { if(debug) out("-- discarding " + i); } else { if(debug) out("-- adding " + i); win.add(i, new Message(null, null, new Long(i))); if(trace && i % 1000 == 0) System.out.println("-- added " + i); while((msg=win.remove()) != null) processMessage(msg); } } while(true) { while((msg=win.remove()) != null) processMessage(msg); } } void processMessage(Message msg) { long i; i=((Long)msg.getObject()).longValue(); if(prev_value + 1 != i) { System.err.println("** processMessage(): removed seqno (" + i + ") is not 1 greater than " + "previous value (" + prev_value + ')'); System.exit(0); } prev_value++; if(trace && i % 1000 == 0) System.out.println("Removed " + i); if(i == num_msgs) { stop=System.currentTimeMillis(); long total=stop-start; double msgs_per_sec=num_msgs / (total/1000.0); double msgs_per_ms=num_msgs / (double)total; System.out.println("Inserting and removing " + num_msgs + " messages into NakReceiverWindow took " + total + "ms"); System.out.println("Msgs/sec: " + msgs_per_sec + ", msgs/ms: " + msgs_per_ms); System.out.println("<enter> to terminate"); try { System.in.read(); } catch(Exception ex) { System.err.println(ex); } System.exit(0); } } static void out(String msg) { System.out.println(msg); } public static void main(String[] args) { NakReceiverWindowStressTest test; int num_msgs=1000; double discard_prob=0.0; boolean trace=false; for(int i=0; i < args.length; i++) { if("-help".equals(args[i])) { help(); return; } if("-num_msgs".equals(args[i])) { num_msgs=Integer.parseInt(args[++i]); continue; } if("-discard".equals(args[i])) { discard_prob=Double.parseDouble(args[++i]); continue; } if("-trace".equals(args[i])) { trace=true; } } test=new NakReceiverWindowStressTest(num_msgs, discard_prob, trace); try { test.start(); } catch(IOException e) { e.printStackTrace(); } catch(InterruptedException e) { e.printStackTrace(); } } static void help() { System.out.println("NakReceiverWindowStressTest [-help] [-num_msgs <number>] [-discard <probability>] " + "[-trace]"); } }