package com.ustcinfo.rpc.client;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import com.ustcinfo.rpc.annotation.Codecs;
public abstract class AbstractClientInvocationHandler implements InvocationHandler {
private List<InetSocketAddress> servers;
private int clientNums;
private int connectTimeout;
private String targetInstanceName;
private Codecs codecType;
// per method timeout,some special method use methodName.toLowerCase to set timeout,other use *
private Map<String, Integer> methodTimeouts;
public AbstractClientInvocationHandler(List<InetSocketAddress> servers,int clientNums,int connectTimeout,
String targetInstanceName,Map<String, Integer> methodTimeouts,
Codecs codecType){
this.servers = Collections.unmodifiableList(servers);
this.clientNums = clientNums;
this.connectTimeout = connectTimeout;
this.methodTimeouts = methodTimeouts;
this.targetInstanceName = targetInstanceName;
this.codecType = codecType;
}
public void updateServers(List<InetSocketAddress> servers){
this.servers = Collections.unmodifiableList(servers);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
InetSocketAddress server = null;
if(servers.size() == 1){
server = servers.get(0);
}
else{
// random is not thread-safe,so...
Random random = new Random();
server = servers.get(random.nextInt(servers.size()));
}
Client client = getClientFactory().get(server.getAddress().getHostAddress(), server.getPort(), connectTimeout, clientNums);
String methodName = method.getName();
int timeout = 0;
if(methodTimeouts.containsKey(methodName.toLowerCase())){
timeout = methodTimeouts.get(methodName);
}
else{
timeout = methodTimeouts.get("*");
}
return client.invokeSync(targetInstanceName, methodName, method.getParameterTypes(), args, timeout, codecType);
}
public abstract ClientFactory getClientFactory();
}