package code.google.nfs.rpc.benchmark;
/**
* nfs-rpc
* Apache License
*
* http://code.google.com/p/nfs-rpc (c) 2011
*/
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import code.google.nfs.rpc.Codecs;
import com.google.protobuf.ByteString;
/**
* RPC Benchmark client thread
*
* @author <a href="mailto:bluedavy@gmail.com">bluedavy</a>
*/
public class RPCBenchmarkClientRunnable implements ClientRunnable {
private static final Log LOGGER = LogFactory.getLog(RPCBenchmarkClientRunnable.class);
private int requestSize;
private CyclicBarrier barrier;
private CountDownLatch latch;
private long endTime;
private boolean running = true;
private BenchmarkTestService testService;
// response time spread
private long[] responseSpreads = new long[9];
// error request per second
private long[] errorTPS = null;
// error response times per second
private long[] errorResponseTimes = null;
// tps per second
private long[] tps = null;
// response times per second
private long[] responseTimes = null;
// benchmark startTime
private long startTime;
// benchmark maxRange
private int maxRange;
private int codecType;
public RPCBenchmarkClientRunnable(BenchmarkTestService testService, int requestSize, CyclicBarrier barrier,
CountDownLatch latch, long startTime, long endTime, int codecType) {
this.testService = testService;
this.codecType = codecType;
this.requestSize = requestSize;
this.barrier = barrier;
this.latch = latch;
this.startTime = startTime;
this.endTime = endTime;
maxRange = (Integer.parseInt(String.valueOf((endTime - startTime))) / 1000) + 1;
errorTPS = new long[maxRange];
errorResponseTimes = new long[maxRange];
tps = new long[maxRange];
responseTimes = new long[maxRange];
// init
for (int i = 0; i < maxRange; i++) {
errorTPS[i] = 0;
errorResponseTimes[i] = 0;
tps[i] = 0;
responseTimes[i] = 0;
}
}
public void run() {
try {
barrier.await();
}
catch (Exception e) {
// IGNORE
}
if(codecType == Codecs.PB_CODEC){
runPB();
}
else{
runJavaAndHessian();
}
latch.countDown();
}
private void runJavaAndHessian(){
while (running) {
Object requestObject = new RequestObject(requestSize);
long beginTime = System.currentTimeMillis();
if (beginTime >= endTime) {
running = false;
break;
}
try {
Object response = testService.execute(requestObject);
long currentTime = System.currentTimeMillis();
if(beginTime <= startTime){
continue;
}
long consumeTime = currentTime - beginTime;
sumResponseTimeSpread(consumeTime);
int range = Integer.parseInt(String.valueOf(beginTime - startTime))/1000;
if(range >= maxRange){
// IGNORE
continue;
}
if(((ResponseObject)response).getBytes() !=null ){
tps[range] = tps[range] + 1;
responseTimes[range] = responseTimes[range] + consumeTime;
}
else{
LOGGER.error("server return response is null");
errorTPS[range] = errorTPS[range] + 1;
errorResponseTimes[range] = errorResponseTimes[range] + consumeTime;
}
}
catch (Exception e) {
LOGGER.error("testService.execute error",e);
long currentTime = System.currentTimeMillis();
if(beginTime <= startTime){
continue;
}
long consumeTime = currentTime - beginTime;
sumResponseTimeSpread(consumeTime);
int range = Integer.parseInt(String.valueOf(beginTime - startTime))/1000;
if(range >= maxRange){
// IGNORE
continue;
}
errorTPS[range] = errorTPS[range] + 1;
errorResponseTimes[range] = errorResponseTimes[range] + consumeTime;
}
}
}
private void runPB(){
while (running) {
code.google.nfs.rpc.benchmark.PB.RequestObject.Builder objectBuilder = PB.RequestObject.newBuilder();
objectBuilder.setBytesObject(ByteString.copyFrom(new byte[requestSize]));
PB.RequestObject requestObject = objectBuilder.build();
long beginTime = System.currentTimeMillis();
if (beginTime >= endTime) {
running = false;
break;
}
try {
Object response = testService.executePB(requestObject);
long currentTime = System.currentTimeMillis();
if(beginTime <= startTime){
continue;
}
long consumeTime = currentTime - beginTime;
sumResponseTimeSpread(consumeTime);
int range = Integer.parseInt(String.valueOf(beginTime - startTime))/1000;
if(range >= maxRange){
// IGNORE
continue;
}
if(((PB.ResponseObject)response).getBytesObject().toByteArray().length > 0 ){
tps[range] = tps[range] + 1;
responseTimes[range] = responseTimes[range] + consumeTime;
}
else{
LOGGER.error("server return response is null");
errorTPS[range] = errorTPS[range] + 1;
errorResponseTimes[range] = errorResponseTimes[range] + consumeTime;
}
}
catch (Exception e) {
LOGGER.error("testService.execute error",e);
long currentTime = System.currentTimeMillis();
if(beginTime <= startTime){
continue;
}
long consumeTime = currentTime - beginTime;
sumResponseTimeSpread(consumeTime);
int range = Integer.parseInt(String.valueOf(beginTime - startTime))/1000;
if(range >= maxRange){
// IGNORE
continue;
}
errorTPS[range] = errorTPS[range] + 1;
errorResponseTimes[range] = errorResponseTimes[range] + consumeTime;
}
}
}
public List<long[]> getResults() {
List<long[]> results = new ArrayList<long[]>();
results.add(responseSpreads);
results.add(tps);
results.add(responseTimes);
results.add(errorTPS);
results.add(errorResponseTimes);
return results;
}
private void sumResponseTimeSpread(long responseTime) {
if (responseTime <= 0) {
responseSpreads[0] = responseSpreads[0] + 1;
}
else if (responseTime > 0 && responseTime <= 1) {
responseSpreads[1] = responseSpreads[1] + 1;
}
else if (responseTime > 1 && responseTime <= 5) {
responseSpreads[2] = responseSpreads[2] + 1;
}
else if (responseTime > 5 && responseTime <= 10) {
responseSpreads[3] = responseSpreads[3] + 1;
}
else if (responseTime > 10 && responseTime <= 50) {
responseSpreads[4] = responseSpreads[4] + 1;
}
else if (responseTime > 50 && responseTime <= 100) {
responseSpreads[5] = responseSpreads[5] + 1;
}
else if (responseTime > 100 && responseTime <= 500) {
responseSpreads[6] = responseSpreads[6] + 1;
}
else if (responseTime > 500 && responseTime <= 1000) {
responseSpreads[7] = responseSpreads[7] + 1;
}
else if (responseTime > 1000) {
responseSpreads[8] = responseSpreads[8] + 1;
}
}
}