package de.jpaw.bonaparte.akka.testClient; import java.util.Date; import java.util.concurrent.TimeUnit; import scala.concurrent.duration.Duration; import akka.actor.ActorRef; import akka.actor.ActorSystem; import akka.actor.Props; import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; import akka.routing.RoundRobinRouter; import de.jpaw.bonaparte.akka.EchoActor; import de.jpaw.bonaparte.demorqrs.CreateRq; import de.jpaw.bonaparte.pojos.rqrs.Request; import de.jpaw.bonaparte.pojos.rqrs.Response; public class AkkaBenchmark { private static Date start; static class StartBenchmarkTrigger { } static class StopBenchmarkTrigger { } public static void main(String[] args) throws Exception { int numberOfThreads = 4; int callsPerThread = 100; int delay = 0; if (args.length > 0) { delay = Integer.valueOf(args[0]); } else { System.out.println("Usage: AkkaBenchmark (delay in ms) [(threads) [(calls / thread)]]"); System.exit(1); } if (args.length > 1) { numberOfThreads = Integer.valueOf(args[1]); } if (args.length > 2) { callsPerThread = Integer.valueOf(args[2]); } System.out.println("Starting benchmark with delay " + delay + " ms with " + numberOfThreads + " threads and " + callsPerThread + " calls per thread"); start = new Date(); DummyClassJustToMake2VariablesFinal dummy = new DummyClassJustToMake2VariablesFinal(numberOfThreads, callsPerThread); dummy.runTest(); } public static class DummyClassJustToMake2VariablesFinal { private final int numberOfThreads; private final int callsPerThread; DummyClassJustToMake2VariablesFinal(int numberOfThreads, int callsPerThread) { this.numberOfThreads = numberOfThreads; this.callsPerThread = callsPerThread; } void runTest() { // Create an Akka system ActorSystem system = ActorSystem.create("MySystem"); // create the result listener, which will print the result and // shutdown the system final ActorRef doneListener = system.actorOf(new Props(DoneListener.class), "doneListener"); // create the master ActorRef dispatcher = system.actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new Dispatcher(numberOfThreads, callsPerThread, doneListener); } }), "dispatcher"); // start the calculation dispatcher.tell(new StartBenchmarkTrigger()); } } // #result-listener public static class DoneListener extends UntypedActor { public void onReceive(Object message) { if (message instanceof StopBenchmarkTrigger) { Date stop = new Date(); long millis = stop.getTime() - start.getTime(); System.out.println("Overall result: " + millis / 1000 + " seconds"); getContext().system().shutdown(); } else { unhandled(message); } } } public static class Dispatcher extends UntypedActor { private final int nrOfMessages; private int nrOfResults; private final long start = System.currentTimeMillis(); private final ActorRef listener; private final ActorRef echoServer; public Dispatcher(int nrOfWorkers, int nrOfMessages, ActorRef listener) { this.nrOfMessages = nrOfMessages; this.listener = listener; echoServer = this.getContext().actorOf(new Props(EchoActor.class).withRouter(new RoundRobinRouter(nrOfWorkers)), "echoServer"); } public void onReceive(Object message) { if (message instanceof StartBenchmarkTrigger) { for (int start = 0; start < nrOfMessages; start++) { Request newRequest = CreateRq.createRequest(); newRequest.setSerialNo(start); echoServer.tell(newRequest, getSelf()); } } else if (message instanceof Response) { nrOfResults += 1; if (nrOfResults == nrOfMessages) { // Send the result to the listener Duration duration = Duration.create(System.currentTimeMillis() - start, TimeUnit.MILLISECONDS); listener.tell(new StopBenchmarkTrigger(), getSelf()); // Stops this actor and all its supervised children getContext().stop(getSelf()); } } else { unhandled(message); } } } }