/**
*
*/
package com.github.phantomthief.thrift.client.impl;
import static java.util.stream.Collectors.toList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import org.apache.thrift.TServiceClient;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TTransport;
import com.github.phantomthief.thrift.client.ThriftClient;
import com.github.phantomthief.thrift.client.pool.ThriftConnectionPoolProvider;
import com.github.phantomthief.thrift.client.pool.ThriftServerInfo;
import com.github.phantomthief.thrift.client.pool.impl.DefaultThriftConnectionPoolImpl;
import com.github.phantomthief.thrift.client.utils.FailoverCheckingStrategy;
import com.github.phantomthief.thrift.client.utils.ThriftClientUtils;
/**
* <p>
* FailoverThriftClientImpl class.
* </p>
*
* @author w.vela
* @version $Id: $Id
*/
public class FailoverThriftClientImpl implements ThriftClient {
private final ThriftClient thriftClient;
/**
* <p>
* Constructor for FailoverThriftClientImpl.
* </p>
*
* @param serverInfoProvider a {@link java.util.function.Supplier}
* object.
*/
public FailoverThriftClientImpl(Supplier<List<ThriftServerInfo>> serverInfoProvider) {
this(new FailoverCheckingStrategy<>(), serverInfoProvider, DefaultThriftConnectionPoolImpl
.getInstance());
}
/**
* <p>
* Constructor for FailoverThriftClientImpl.
* </p>
*
* @param failoverCheckingStrategy a
* {@link com.github.phantomthief.thrift.client.utils.FailoverCheckingStrategy}
* object.
* @param serverInfoProvider a {@link java.util.function.Supplier}
* object.
* @param poolProvider a
* {@link com.github.phantomthief.thrift.client.pool.ThriftConnectionPoolProvider}
* object.
*/
public FailoverThriftClientImpl(
FailoverCheckingStrategy<ThriftServerInfo> failoverCheckingStrategy,
Supplier<List<ThriftServerInfo>> serverInfoProvider,
ThriftConnectionPoolProvider poolProvider) {
FailoverStategy failoverStategy = new FailoverStategy(serverInfoProvider, poolProvider,
failoverCheckingStrategy);
this.thriftClient = new ThriftClientImpl(failoverStategy, failoverStategy);
}
/** {@inheritDoc} */
@Override
public <X extends TServiceClient> X iface(Class<X> ifaceClass) {
return thriftClient.iface(ifaceClass);
}
/* (non-Javadoc)
* @see com.github.phantomthief.thrift.client.ThriftClient#iface(java.lang.Class)
*/
/** {@inheritDoc} */
@Override
public <X extends TServiceClient> X iface(Class<X> ifaceClass, int hash) {
return thriftClient.iface(ifaceClass, hash);
}
/* (non-Javadoc)
* @see com.github.phantomthief.thrift.client.ThriftClient#iface(java.lang.Class, int)
*/
/** {@inheritDoc} */
@Override
public <X extends TServiceClient> X iface(Class<X> ifaceClass,
Function<TTransport, TProtocol> protocolProvider, int hash) {
return thriftClient.iface(ifaceClass, protocolProvider, hash);
}
/** {@inheritDoc} */
@Override
public <X extends TServiceClient> X mpiface(Class<X> ifaceClass, String serviceName) {
return thriftClient.mpiface(ifaceClass, serviceName, ThriftClientUtils.randomNextInt());
}
/** {@inheritDoc} */
@Override
public <X extends TServiceClient> X mpiface(Class<X> ifaceClass, String serviceName, int hash) {
return thriftClient.mpiface(ifaceClass, serviceName, TBinaryProtocol::new, hash);
}
/** {@inheritDoc} */
@Override
public <X extends TServiceClient> X mpiface(Class<X> ifaceClass, String serviceName,
Function<TTransport, TProtocol> protocolProvider, int hash) {
return thriftClient.mpiface(ifaceClass, serviceName, protocolProvider, hash);
}
/* (non-Javadoc)
* @see com.github.phantomthief.thrift.client.ThriftClient#iface(java.lang.Class, java.util.function.Function, int)
*/
private class FailoverStategy implements
Supplier<List<ThriftServerInfo>>,
ThriftConnectionPoolProvider {
private final Supplier<List<ThriftServerInfo>> originalServerInfoProvider;
private final ThriftConnectionPoolProvider connectionPoolProvider;
private final FailoverCheckingStrategy<ThriftServerInfo> failoverCheckingStrategy;
private FailoverStategy(Supplier<List<ThriftServerInfo>> originalServerInfoProvider,
ThriftConnectionPoolProvider connectionPoolProvider,
FailoverCheckingStrategy<ThriftServerInfo> failoverCheckingStrategy) {
this.originalServerInfoProvider = originalServerInfoProvider;
this.connectionPoolProvider = connectionPoolProvider;
this.failoverCheckingStrategy = failoverCheckingStrategy;
}
/* (non-Javadoc)
* @see java.util.function.Supplier#get()
*/
@Override
public List<ThriftServerInfo> get() {
Set<ThriftServerInfo> failedServers = failoverCheckingStrategy.getFailed();
return originalServerInfoProvider.get().stream()
.filter(i -> !failedServers.contains(i)).collect(toList());
}
/* (non-Javadoc)
* @see com.github.phantomthief.thrift.client.pool.ThriftConnectionPoolProvider#getConnection(com.github.phantomthief.thrift.client.pool.ThriftServerInfo)
*/
@Override
public TTransport getConnection(ThriftServerInfo thriftServerInfo) {
return connectionPoolProvider.getConnection(thriftServerInfo);
}
/* (non-Javadoc)
* @see com.github.phantomthief.thrift.client.pool.ThriftConnectionPoolProvider#returnConnection(com.github.phantomthief.thrift.client.pool.ThriftServerInfo, org.apache.thrift.transport.TTransport)
*/
@Override
public void returnConnection(ThriftServerInfo thriftServerInfo, TTransport transport) {
connectionPoolProvider.returnConnection(thriftServerInfo, transport);
}
/* (non-Javadoc)
* @see com.github.phantomthief.thrift.client.pool.ThriftConnectionPoolProvider#returnBrokenConnection(com.github.phantomthief.thrift.client.pool.ThriftServerInfo, org.apache.thrift.transport.TTransport)
*/
@Override
public void returnBrokenConnection(ThriftServerInfo thriftServerInfo, TTransport transport) {
failoverCheckingStrategy.fail(thriftServerInfo);
connectionPoolProvider.returnBrokenConnection(thriftServerInfo, transport);
}
}
}