org.jgroups.tests.RoundTrip Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including
all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and
JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
The newest version!
package org.jgroups.tests;
import org.jgroups.Global;
import org.jgroups.tests.rt.RtReceiver;
import org.jgroups.tests.rt.RtTransport;
import org.jgroups.tests.rt.transports.*;
import org.jgroups.util.AverageMinMax;
import org.jgroups.util.Bits;
import org.jgroups.util.Promise;
import org.jgroups.util.Util;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Class that measure RTT for multicast messages between 2 cluster members. See {@link RpcDispatcherSpeedTest} for
* RPCs. Note that request and response times are measured using {@link System#nanoTime()} which might yield incorrect
* values when run on different cores, so these numbers may not be reliable.
* Running this on different nodes will not yield correct results for request- and response-latencies, but should be ok
* for round-trip times. *If* times across nodes are synchronized, flag -use-wall-clock can switch to currentTimeMillis()
* which gives more meaningful results for request- and response-latency across boxes.
* @author Bela Ban
*/
public class RoundTrip implements RtReceiver {
protected RtTransport tp;
protected int num_msgs=50000;
protected int num_senders=1; // number of sender threads
protected boolean details;
protected boolean use_ms; // typically we use us, but if the flag is true, we use ms
protected static final byte REQ=0, RSP=1, DONE=2;
// | REQ or RSP | index (short) | time (long) |
public static final int PAYLOAD=Global.BYTE_SIZE + Global.SHORT_SIZE + Global.LONG_SIZE;
protected Sender[] senders;
protected final AverageMinMax req_latency=new AverageMinMax(); // client -> server
protected final AverageMinMax rsp_latency=new AverageMinMax(); // server -> client
protected static final Map TRANSPORTS=new HashMap<>(16);
static {
TRANSPORTS.put("jg", JGroupsTransport.class.getName());
TRANSPORTS.put("tcp", TcpTransport.class.getName());
TRANSPORTS.put("nio", NioTransport.class.getName());
TRANSPORTS.put("server", ServerTransport.class.getName());
TRANSPORTS.put("udp", UdpTransport.class.getName());
}
public RoundTrip(boolean use_ms) {
this.use_ms=use_ms;
}
protected void start(String transport, String[] args) throws Exception {
tp=create(transport);
tp.receiver(this);
try {
tp.start(args);
loop();
}
finally {
tp.stop();
}
}
/** On the server: receive a request, send a response. On the client: send a request, wait for the response */
public void receive(Object sender, byte[] req_buf, int offset, int length) {
switch(req_buf[offset]) {
case REQ:
short id=Bits.readShort(req_buf, 1+offset);
long time=time(use_ms) - Bits.readLong(req_buf, 3+offset);
byte[] rsp_buf=new byte[PAYLOAD];
rsp_buf[0]=RSP;
Bits.writeShort(id, rsp_buf, 1);
try {
Bits.writeLong(time(use_ms), rsp_buf, 3);
tp.send(sender, rsp_buf, 0, rsp_buf.length);
}
catch(Exception e) {
e.printStackTrace();
}
synchronized(req_latency) {
req_latency.add(time);
}
break;
case RSP:
id=Bits.readShort(req_buf, 1);
time=time(use_ms) - Bits.readLong(req_buf, 3);
senders[id].promise.setResult(true); // notify the sender of the response
synchronized(rsp_latency) {
rsp_latency.add(time);
}
break;
case DONE:
System.out.printf(Util.bold("req-latency = min/avg/max: %d / %.2f / %d %s\n"),
req_latency.min(), req_latency.average(), req_latency.max(), unit());
req_latency.clear();
break;
default:
throw new IllegalArgumentException("first byte needs to be either REQ or RSP but not " + req_buf[0]);
}
}
protected void loop() {
boolean looping=true;
while(looping) {
int c=Util.keyPress(String.format("[1] send [2] num_msgs (%d) [3] senders (%d)\n" +
"[d] details (%b) [x] exit\n",
num_msgs, num_senders, details));
try {
switch(c) {
case '1':
sendRequests();
break;
case '2':
num_msgs=Util.readIntFromStdin("num_msgs: ");
break;
case '3':
num_senders=Util.readIntFromStdin("num_senders: ");
break;
case 'd':
details=!details;
break;
case 'x':
case -1:
looping=false;
break;
}
}
catch(Throwable t) {
t.printStackTrace();
}
}
}
protected void sendRequests() throws Exception {
List