package edu.berkeley.thebes.twopl.common;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransportException;
import edu.berkeley.thebes.common.clustering.RoutingHash;
import edu.berkeley.thebes.common.config.Config;
import edu.berkeley.thebes.common.thrift.ServerAddress;
import edu.berkeley.thebes.twopl.common.thrift.TwoPLMasterReplicaService;
import edu.berkeley.thebes.twopl.common.thrift.TwoPLThriftUtil;
import java.util.ArrayList;
import java.util.List;
/** Helps route traffic to the master of each replica set. */
public class TwoPLMasterRouter {
/** Contains the ordered list of master replicas, one per set of replicas. */
private List<TwoPLMasterReplicaService.Client> masterReplicas;
public TwoPLMasterRouter() throws TTransportException {
List<ServerAddress> serverIPs = Config.getMasterServers();
masterReplicas = new ArrayList<TwoPLMasterReplicaService.Client>(serverIPs.size());
for (ServerAddress server : serverIPs) {
masterReplicas.add(TwoPLThriftUtil.getMasterReplicaServiceClient(
server.getIP(), server.getPort()));
}
}
public TwoPLMasterReplicaService.Client getMasterByKey(String key) throws TTransportException {
int index = RoutingHash.hashKey(key, masterReplicas.size());
TwoPLMasterReplicaService.Client client = masterReplicas.get(index);
TSocket sock = (TSocket) client.getInputProtocol().getTransport();
if (!sock.isOpen()) {
// TODO: Logger
System.err.println("ERROR: Client for key '" + key + "' has closed! Opening new channel.");
client = TwoPLThriftUtil.getMasterReplicaServiceClient(
sock.getSocket().getInetAddress().getHostAddress(),
sock.getSocket().getPort());
masterReplicas.set(index, client);
}
return client;
}
public ServerAddress getMasterAddressByKey(String key) {
List<ServerAddress> servers = Config.getMasterServers();
return servers.get(RoutingHash.hashKey(key, servers.size()));
}
public void refreshMasterForKey(String key) throws TTransportException {
int index = RoutingHash.hashKey(key, masterReplicas.size());
TwoPLMasterReplicaService.Client client = masterReplicas.get(index);
TSocket sock = (TSocket) client.getInputProtocol().getTransport();
// TODO: Logger
System.err.println("WARNING: Client for key '" + key + "' may have closed! Opening new channel.");
client = TwoPLThriftUtil.getMasterReplicaServiceClient(
sock.getSocket().getInetAddress().getHostAddress(),
sock.getSocket().getPort());
masterReplicas.set(index, client);
}
}