package com.meidusa.amoeba.benchmark;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import org.apache.log4j.Logger;
import com.meidusa.amoeba.benchmark.AbstractBenchmark.TaskRunnable;
import com.meidusa.amoeba.net.AuthingableConnection;
import com.meidusa.amoeba.net.Connection;
import com.meidusa.amoeba.net.MessageHandler;
import com.meidusa.amoeba.net.packet.Packet;
public abstract class AbstractBenchmarkClient<T extends Packet> implements MessageHandler{
private static Logger logger = Logger.getLogger(AbstractBenchmarkClient.class);
private boolean debug = false;
private int timeout = -1;
private Properties properties;
long min = System.nanoTime();
long start = 0;
long max = 0;
long end = min;
long next = min;
long count = 0;
protected CountDownLatch requestLatcher;
protected CountDownLatch responseLatcher;
protected TaskRunnable task;
private AbstractBenchmark benchmark;
private Connection connection;
private MessageHandler connOldMessageHandler = null;
public AbstractBenchmark getBenchmark() {
return benchmark;
}
public void setBenchmark(AbstractBenchmark benchmark) {
this.benchmark = benchmark;
}
public Connection getConnection() {
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public void putAllRequestProperties(Map source){
if(properties == null){
properties = new Properties();
}
properties.putAll(source);
}
public Properties getRequestProperties(){
return properties;
}
public AbstractBenchmarkClient(Connection connection, CountDownLatch requestLatcher,CountDownLatch responseLatcher,TaskRunnable task) {
this.connection = connection;
start = System.nanoTime();
this.requestLatcher = requestLatcher;
this.responseLatcher = responseLatcher;
this.task = task;
connOldMessageHandler = connection.getMessageHandler();
connection.setMessageHandler(this );
}
public Map getNextRequestContextMap(){
return this.benchmark.getNextRequestContextMap();
}
public abstract T createRequestPacket();
public abstract T decodeRecievedPacket(byte[] message);
public void startBenchmark(){
postPacketToServer();
}
protected void afterMessageRecieved(byte[] message){
}
protected void doReceiveMessage(byte[] message) {
boolean completed = responseIsCompleted(message);
if (debug) {
T t = decodeRecievedPacket(message);
System.out.println("<<--" + t);
}
afterMessageRecieved(message);
if(completed){
end = System.nanoTime();
long current = end - next;
next = end;
min = Math.min(min, current);
max = Math.max(max, current);
count++;
afterResponseCompleted();
}
}
public void handleMessage(Connection conn){
if(conn instanceof AuthingableConnection){
if(!((AuthingableConnection)conn).isAuthenticated()){
connOldMessageHandler.handleMessage(conn);
}else{
byte[] message = null;
while((message = conn.getInQueue().getNonBlocking()) != null){
doReceiveMessage(message);
}
}
}else{
connOldMessageHandler.handleMessage(conn);
}
}
protected boolean responseIsCompleted(byte[] message){
return true;
}
protected void afterResponseCompleted(){
responseLatcher.countDown();
if(task.running){
if(requestLatcher.getCount()>0){
requestLatcher.countDown();
postPacketToServer();
}
}
}
protected void postPacketToServer(){
T packet = createRequestPacket();
ByteBuffer buffer = packet.toByteBuffer(connection);
if (debug) {
System.out.println("--->>" + packet);
}
connection.postMessage(buffer);
}
public void init() {
}
/*public boolean checkIdle(long now) {
boolean isTimeOut = false;
if(timeout>0){
if (connection.isClosed()) {
isTimeOut = true;
}
long idleMillis = now - connection._lastEvent;
if (idleMillis < timeout) {
isTimeOut = false;
}else{
isTimeOut = true;
}
}else{
isTimeOut = false;
}
if(isTimeOut){
logger.warn("socket id="+this.getSocketId()+" receive time out="+(now - _lastEvent));
}
return isTimeOut;
}*/
}