org.jgroups.tests.RoundTrip Maven / Gradle / Ivy
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
© 2015 - 2025 Weber Informatics LLC | Privacy Policy