package org.jgroups.tests;
import org.jgroups.*;
import org.jgroups.util.Util;
/**
* Class that measure RTT between a client and server
* @author Bela Ban
*/
public class RoundTrip extends ReceiverAdapter {
JChannel channel;
String props;
int num=1000;
int msg_size=10;
boolean server=false;
final byte[] RSP_BUF=new byte[]{1}; // 1=response
int num_responses=0;
final Object mutex=new Object(); // to sync sending and reception of a message
private void start(boolean server, int num, int msg_size, String props) throws Exception {
this.server=server;
this.num=num;
this.msg_size=msg_size;
this.props=props;
channel=new JChannel(props);
channel.setReceiver(this);
channel.connect("rt");
if(server) {
System.out.println("server started (ctrl-c to kill)");
while(true) {
Util.sleep(60000);
}
}
else {
channel.setDiscardOwnMessages(true);
System.out.println("sending " + num + " requests");
sendRequests();
channel.close();
}
}
/**
* On the server: receive a request, send a response. On the client: send a request, wait for the response
* @param msg
*/
public void receive(Message msg) {
byte[] buf=msg.getRawBuffer();
if(buf == null) {
System.err.println("buffer was null !");
return;
}
if(buf[0] == 0) { // request
if(!server) {// client ignores requests
return;
}
// System.out.println("-- SERVER: received " + num_requests + " requests");
Message response=new Message(msg.getSrc(), null, null);
response.setBuffer(RSP_BUF, 0, RSP_BUF.length);
try {
channel.send(response);
}
catch(Exception e) {
e.printStackTrace();
}
}
else { // response
synchronized(mutex) {
num_responses++;
// System.out.println("-- SERVER: received " + num_responses + " responses");
mutex.notify();
}
}
}
private void sendRequests() {
byte[] buf=new byte[msg_size];
long start, stop, total;
double requests_per_sec;
double ms_per_req;
Message msg;
int print=num / 10;
int count=0;
num_responses=0;
for(int i=0; i < buf.length; i++) {
buf[i]=0; // 0=request
}
/* Address dest;
Vector v=new Vector(channel.getView().getMembers());
v.remove(channel.getLocalAddress());
dest=(Address)v.firstElement();*/
start=System.currentTimeMillis();
for(int i=0; i < num; i++) {
msg=new Message(null, null, null);
msg.setBuffer(buf);
try {
channel.send(msg);
synchronized(mutex) {
while(num_responses != count +1) {
mutex.wait(1000);
}
count=num_responses;
if(num_responses >= num) {
System.out.println("received all responses (" + num_responses + ")");
break;
}
}
if(num_responses % print == 0) {
System.out.println("- received " + num_responses);
}
}
catch(Exception e) {
e.printStackTrace();
}
}
stop=System.currentTimeMillis();
total=stop-start;
requests_per_sec=num / (total / 1000.0);
ms_per_req=total / (double)num;
System.out.println("Took " + total + "ms for " + num + " requests: " + requests_per_sec +
" requests/sec, " + ms_per_req + " ms/request");
}
public static void main(String[] args) throws Exception {
boolean server=false;
int num=100;
int msg_size=10; // 10 bytes
String props=null;
for(int i=0; i < args.length; i++) {
if(args[i].equals("-num")) {
num=Integer.parseInt(args[++i]);
continue;
}
if(args[i].equals("-server")) {
server=true;
continue;
}
if(args[i].equals("-size")) {
msg_size=Integer.parseInt(args[++i]);
continue;
}
if(args[i].equals("-props")) {
props=args[++i];
continue;
}
help();
return;
}
new RoundTrip().start(server, num, msg_size, props);
}
private static void help() {
System.out.println("RoundTrip [-server] [-num <number of messages>] " +
"[-size <size of each message (in bytes)>] [-props <properties>]");
}
}