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.TimeScheduler2; import org.jgroups.util.Util; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; public class NakReceiverWindowStressTest2 { static int NUM_THREADS=10; static int NUM_MSGS=1000000; static final Message MSG=new Message(false); static final AtomicInteger added=new AtomicInteger(0); static final AtomicInteger removed=new AtomicInteger(0); public static void main(String[] args) throws InterruptedException { for(int i=0; i < args.length; i++) { if(args[i].startsWith("-h")) { System.out.println("NakReceiverWindowStressTest2 [-num messages] [-adders <number of adder threads>]"); return; } if(args[i].equals("-num")) { NUM_MSGS=Integer.parseInt(args[++i]); continue; } if(args[i].equals("-adders")) { NUM_THREADS=Integer.parseInt(args[++i]); } } Address sender=Util.createRandomAddress("A"); TimeScheduler2 timer=new TimeScheduler2(10); NakReceiverWindow win=new NakReceiverWindow(sender, new Retransmitter.RetransmitCommand() { public void retransmit(long first_seqno, long last_seqno, Address sender) { System.out.println("-- retransmit(" + first_seqno + "-" + last_seqno); } }, 0, timer, true); // win.setRetransmitTimeouts(new ExponentialInterval(1000)); final CountDownLatch latch=new CountDownLatch(1); Remover remover=new Remover(win, latch); remover.start(); Adder[] adders=new Adder[NUM_THREADS]; for(int i=0; i < adders.length; i++) { adders[i]=new Adder(win, latch, added); adders[i].start(); } Util.sleep(1000); long start=System.currentTimeMillis(); latch.countDown(); while(remover.isAlive()) { System.out.println("added messages: " + added + ", removed messages: " + removed); remover.join(2000); } long diff=System.currentTimeMillis() - start; System.out.println("added messages: " + added + ", removed messages: " + removed); System.out.println("took " + diff + " ms to insert and remove " + NUM_MSGS + " messages"); win.destroy(); timer.stop(); } protected static class Adder extends Thread { protected final NakReceiverWindow win; protected final AtomicInteger num; protected final CountDownLatch latch; public Adder(NakReceiverWindow win, CountDownLatch latch, AtomicInteger num) { this.win=win; this.num=num; this.latch=latch; setName("Adder"); } public void run() { try { latch.await(); } catch(InterruptedException e) { e.printStackTrace(); } while(true) { int seqno=num.incrementAndGet(); if(seqno > NUM_MSGS) { num.decrementAndGet(); break; } win.add(seqno, MSG); } } } protected static class Remover extends Thread { protected final NakReceiverWindow win; protected final CountDownLatch latch; public Remover(NakReceiverWindow win, CountDownLatch latch) { this.win=win; this.latch=latch; setName("Remover"); } public void run() { try { latch.await(); } catch(InterruptedException e) { e.printStackTrace(); } int cnt=0; final AtomicBoolean processing=new AtomicBoolean(false); for(;;) { List<Message> msgs=win.removeMany(processing, true, 100); if(msgs != null) { for(Message msg: msgs) { cnt++; removed.incrementAndGet(); } continue; } if(cnt >= NUM_MSGS) break; Util.sleep(500); } System.out.println("-- removed " + cnt + " messages"); } } }