/** * Copyright 2015 Santhosh Kumar Tekuri * * The JLibs authors license this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package jlibs.examples.wamp4j; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import jlibs.wamp4j.WAMPSerialization; import jlibs.wamp4j.client.CallListener; import jlibs.wamp4j.client.PublishListener; import jlibs.wamp4j.client.WAMPClient; import jlibs.wamp4j.error.WAMPException; import jlibs.wamp4j.msg.ResultMessage; import jlibs.wamp4j.netty.NettyClientEndpoint; import java.net.URI; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; /** * @author Santhosh Kumar Tekuri */ public class WAMPPublish{ public static void main(String[] args) throws Exception{ if(args.length!=7){ System.err.println("arguments: <uri> <serialization> <realm> <topic> <blocking> <clients> <interval>"); System.exit(1); } URI uri = URI.create(args[0]); WAMPSerialization serialization = WAMPSerialization.valueOf(args[1]); String realm = args[2]; final String topic = args[3]; final boolean blocking = Boolean.valueOf(args[4]); int clients = Integer.parseInt(args[5]); long interval = Long.parseLong(args[6]); final CountDownLatch latch = new CountDownLatch(1+clients); final PublishThread threads[] = new PublishThread[clients]; for(int i=0; i<threads.length; i++){ final int index = i; new WAMPClient(new NettyClientEndpoint(), uri, realm, serialization).connect(new SessionAdapter(){ @Override public void onOpen(WAMPClient client){ System.out.println("client"+index+" connected to wamp-router"); PublishThread thread; if(blocking) thread = new BlockingPublishThread(client, topic, latch); else thread = new NonBlockingPublishThread(client, topic, latch); threads[index] = thread; thread.start(); } }); } latch.countDown(); latch.await(); Runtime runtime = Runtime.getRuntime(); System.out.printf("%5s %8s %7s %7s %10s %6s %7s %n", "Time", "Requests", "Replies", "Errors", "Throughput", "Memory", "Pending"); long prev = System.nanoTime(); long begin = prev; Thread.sleep(interval); long totalRequests = 0; long totalReplies = 0; while(true){ long cur = System.nanoTime(); long requests = 0; long replies = 0; long errors = 0; for(PublishThread thread : threads){ requests += thread.requests.getAndSet(0); replies += thread.replies.getAndSet(0); errors += thread.errors.getAndSet(0); } totalRequests += requests; totalReplies += replies; double usedMemory = (runtime.totalMemory()- runtime.freeMemory())/(1024*1024.0); long nano = cur-begin; long sec = TimeUnit.NANOSECONDS.toSeconds(nano); nano = nano-TimeUnit.SECONDS.toNanos(sec); long min = TimeUnit.SECONDS.toMinutes(sec); sec = sec-TimeUnit.MINUTES.toSeconds(min); double duration = ((double)(cur-prev))/ TimeUnit.SECONDS.toNanos(1); double throughput = (double)(replies+errors)/duration; System.out.printf("\r%02d:%02d %8d %7d %7d %10.2f %6.2f %7d", min, sec, requests, replies, errors, throughput, usedMemory, (totalRequests-totalReplies)); prev = cur; Thread.sleep(interval); } } } abstract class PublishThread extends Thread{ private static int count = 0; final WAMPClient client; final String topic; final CountDownLatch latch; final AtomicLong requests = new AtomicLong(); final AtomicLong replies = new AtomicLong(); final AtomicLong latencies = new AtomicLong(); final AtomicLong errors = new AtomicLong(); public PublishThread(WAMPClient client, String topic, CountDownLatch latch){ super("PublishThread"+count++); this.client = client; this.topic = topic; this.latch = latch; } public void run(){ latch.countDown(); try{ latch.await(); doRun(); }catch(InterruptedException e){ e.printStackTrace(); } } protected abstract void doRun(); } class BlockingPublishListener implements PublishListener{ public WAMPException error; @Override public void onPublish(WAMPClient client){ synchronized(this){ notifyAll(); } } @Override public void onError(WAMPClient client, WAMPException error){ synchronized(this){ this.error = error; notifyAll(); } } } class BlockingPublishThread extends PublishThread{ public BlockingPublishThread(WAMPClient client, String topic, CountDownLatch latch){ super(client, topic, latch); } private final BlockingPublishListener listener = new BlockingPublishListener(); @Override protected void doRun(){ long requests = 0; long replies = 0; long errors = 0; while(!Thread.interrupted()){ ++requests; try{ long begin = System.nanoTime(); listener.error = null; synchronized(listener){ client.publish(null, topic, null, null, listener); listener.wait(); } if(listener.error!=null) throw listener.error; latencies.addAndGet(System.nanoTime()-begin); ++replies; }catch(Throwable throwable){ if(throwable instanceof InterruptedException) break; ++errors; throwable.printStackTrace(); } } this.requests.set(requests); this.replies.set(replies); this.errors.set(errors); } } class NonBlockingPublishThread extends PublishThread implements PublishListener{ public NonBlockingPublishThread(WAMPClient client, String procedure, CountDownLatch latch){ super(client, procedure, latch); } @Override protected void doRun(){ while(!Thread.interrupted()){ client.publish(null, topic, null, null, this); requests.incrementAndGet(); } } @Override public void onPublish(WAMPClient client){ replies.incrementAndGet(); } @Override public void onError(WAMPClient client, WAMPException error){ errors.incrementAndGet(); error.printStackTrace(); } }