use of com.twitter.distributedlog.thrift.service.ServerInfo in project distributedlog by twitter.
the class ProxyClientManager method run.
@Override
public void run(Timeout timeout) throws Exception {
if (timeout.isCancelled() || closed) {
return;
}
if (periodicHandshakeEnabled) {
final boolean syncOwnerships;
syncOwnerships = lastOwnershipSyncStopwatch.elapsed(TimeUnit.MILLISECONDS) >= clientConfig.getPeriodicOwnershipSyncIntervalMs();
final Set<SocketAddress> hostsSnapshot = hostProvider.getHosts();
final AtomicInteger numHosts = new AtomicInteger(hostsSnapshot.size());
final AtomicInteger numStreams = new AtomicInteger(0);
final AtomicInteger numSuccesses = new AtomicInteger(0);
final AtomicInteger numFailures = new AtomicInteger(0);
final ConcurrentMap<SocketAddress, Integer> streamDistributions = new ConcurrentHashMap<SocketAddress, Integer>();
final Stopwatch stopwatch = Stopwatch.createStarted();
for (SocketAddress host : hostsSnapshot) {
final SocketAddress address = host;
final ProxyClient client = getClient(address);
handshake(address, client, new FutureEventListener<ServerInfo>() {
@Override
public void onSuccess(ServerInfo serverInfo) {
numStreams.addAndGet(serverInfo.getOwnershipsSize());
numSuccesses.incrementAndGet();
notifyHandshakeSuccess(address, client, serverInfo, false, stopwatch);
if (clientConfig.isHandshakeTracingEnabled()) {
streamDistributions.putIfAbsent(address, serverInfo.getOwnershipsSize());
}
complete();
}
@Override
public void onFailure(Throwable cause) {
numFailures.incrementAndGet();
notifyHandshakeFailure(address, client, cause, stopwatch);
complete();
}
private void complete() {
if (0 == numHosts.decrementAndGet()) {
if (syncOwnerships) {
logger.info("Periodic handshaked with {} hosts : {} streams returned," + " {} hosts succeeded, {} hosts failed", new Object[] { hostsSnapshot.size(), numStreams.get(), numSuccesses.get(), numFailures.get() });
if (clientConfig.isHandshakeTracingEnabled()) {
logger.info("Periodic handshaked stream distribution : {}", streamDistributions);
}
}
}
}
}, false, syncOwnerships);
}
if (syncOwnerships) {
lastOwnershipSyncStopwatch.reset().start();
}
}
scheduleHandshake();
}
use of com.twitter.distributedlog.thrift.service.ServerInfo in project distributedlog by twitter.
the class ProxyClientManager method handshake.
/**
* Handshake with all proxies.
*
* NOTE: this is a synchronous call.
*/
public void handshake() {
Set<SocketAddress> hostsSnapshot = hostProvider.getHosts();
logger.info("Handshaking with {} hosts.", hostsSnapshot.size());
final CountDownLatch latch = new CountDownLatch(hostsSnapshot.size());
final Stopwatch stopwatch = Stopwatch.createStarted();
for (SocketAddress host : hostsSnapshot) {
final SocketAddress address = host;
final ProxyClient client = getClient(address);
handshake(address, client, new FutureEventListener<ServerInfo>() {
@Override
public void onSuccess(ServerInfo serverInfo) {
notifyHandshakeSuccess(address, client, serverInfo, true, stopwatch);
latch.countDown();
}
@Override
public void onFailure(Throwable cause) {
notifyHandshakeFailure(address, client, cause, stopwatch);
latch.countDown();
}
}, true, true);
}
try {
latch.await(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
logger.warn("Interrupted on handshaking with servers : ", e);
}
}
use of com.twitter.distributedlog.thrift.service.ServerInfo in project distributedlog by twitter.
the class ProxyClientManager method createClient.
/**
* Create a client to proxy <code>address</code>.
*
* @param address
* proxy address
* @return proxy client
*/
public ProxyClient createClient(final SocketAddress address) {
final ProxyClient sc = clientBuilder.build(address);
ProxyClient oldSC = address2Services.putIfAbsent(address, sc);
if (null != oldSC) {
sc.close();
return oldSC;
} else {
final Stopwatch stopwatch = Stopwatch.createStarted();
FutureEventListener<ServerInfo> listener = new FutureEventListener<ServerInfo>() {
@Override
public void onSuccess(ServerInfo serverInfo) {
notifyHandshakeSuccess(address, sc, serverInfo, true, stopwatch);
}
@Override
public void onFailure(Throwable cause) {
notifyHandshakeFailure(address, sc, cause, stopwatch);
}
};
// send a ping messaging after creating connections.
handshake(address, sc, listener, true, true);
return sc;
}
}
use of com.twitter.distributedlog.thrift.service.ServerInfo in project distributedlog by twitter.
the class TestProxyClientManager method testPeriodicHandshake.
@Test(timeout = 60000)
public void testPeriodicHandshake() throws Exception {
final int numHosts = 3;
final int numStreamsPerHost = 3;
final int initialPort = 5000;
MockProxyClientBuilder builder = new MockProxyClientBuilder();
Map<SocketAddress, ServerInfo> serverInfoMap = new HashMap<SocketAddress, ServerInfo>();
Map<SocketAddress, MockServerInfoService> mockServiceMap = new HashMap<SocketAddress, MockServerInfoService>();
final Map<SocketAddress, CountDownLatch> hostDoneLatches = new HashMap<SocketAddress, CountDownLatch>();
for (int i = 0; i < numHosts; i++) {
SocketAddress address = createSocketAddress(initialPort + i);
ServerInfo serverInfo = new ServerInfo();
for (int j = 0; j < numStreamsPerHost; j++) {
serverInfo.putToOwnerships(runtime.getMethodName() + "_stream_" + j, address.toString());
}
Pair<MockProxyClient, MockServerInfoService> mockProxyClient = createMockProxyClient(address, serverInfo);
builder.provideProxyClient(address, mockProxyClient.getLeft());
serverInfoMap.put(address, serverInfo);
mockServiceMap.put(address, mockProxyClient.getRight());
hostDoneLatches.put(address, new CountDownLatch(2));
}
final Map<SocketAddress, ServerInfo> results = new HashMap<SocketAddress, ServerInfo>();
final CountDownLatch doneLatch = new CountDownLatch(numHosts);
ProxyListener listener = new ProxyListener() {
@Override
public void onHandshakeSuccess(SocketAddress address, ProxyClient client, ServerInfo serverInfo) {
synchronized (results) {
results.put(address, serverInfo);
CountDownLatch latch = hostDoneLatches.get(address);
if (null != latch) {
latch.countDown();
}
}
doneLatch.countDown();
}
@Override
public void onHandshakeFailure(SocketAddress address, ProxyClient client, Throwable cause) {
}
};
TestHostProvider rs = new TestHostProvider();
ProxyClientManager clientManager = createProxyClientManager(builder, rs, 50L);
clientManager.setPeriodicHandshakeEnabled(false);
clientManager.registerProxyListener(listener);
assertEquals("There should be no clients in the manager", 0, clientManager.getNumProxies());
for (int i = 0; i < numHosts; i++) {
SocketAddress address = createSocketAddress(initialPort + i);
rs.addHost(address);
clientManager.createClient(address);
}
// make sure the first 3 handshakes going through
doneLatch.await();
assertEquals("Handshake should return server info", numHosts, results.size());
assertTrue("Handshake should get all server infos", Maps.difference(serverInfoMap, results).areEqual());
// update server info
for (int i = 0; i < numHosts; i++) {
SocketAddress address = createSocketAddress(initialPort + i);
ServerInfo serverInfo = new ServerInfo();
for (int j = 0; j < numStreamsPerHost; j++) {
serverInfo.putToOwnerships(runtime.getMethodName() + "_new_stream_" + j, address.toString());
}
MockServerInfoService service = mockServiceMap.get(address);
serverInfoMap.put(address, serverInfo);
service.updateServerInfo(serverInfo);
}
clientManager.setPeriodicHandshakeEnabled(true);
for (int i = 0; i < numHosts; i++) {
SocketAddress address = createSocketAddress(initialPort + i);
CountDownLatch latch = hostDoneLatches.get(address);
latch.await();
}
assertTrue("Periodic handshake should update all server infos", Maps.difference(serverInfoMap, results).areEqual());
}
use of com.twitter.distributedlog.thrift.service.ServerInfo in project distributedlog by twitter.
the class TestProxyClientManager method testHandshake.
@Test(timeout = 60000)
public void testHandshake() throws Exception {
final int numHosts = 3;
final int numStreamsPerHost = 3;
final int initialPort = 4000;
MockProxyClientBuilder builder = new MockProxyClientBuilder();
Map<SocketAddress, ServerInfo> serverInfoMap = new HashMap<SocketAddress, ServerInfo>();
for (int i = 0; i < numHosts; i++) {
SocketAddress address = createSocketAddress(initialPort + i);
ServerInfo serverInfo = new ServerInfo();
for (int j = 0; j < numStreamsPerHost; j++) {
serverInfo.putToOwnerships(runtime.getMethodName() + "_stream_" + j, address.toString());
}
Pair<MockProxyClient, MockServerInfoService> mockProxyClient = createMockProxyClient(address, serverInfo);
builder.provideProxyClient(address, mockProxyClient.getLeft());
serverInfoMap.put(address, serverInfo);
}
final Map<SocketAddress, ServerInfo> results = new HashMap<SocketAddress, ServerInfo>();
final CountDownLatch doneLatch = new CountDownLatch(2 * numHosts);
ProxyListener listener = new ProxyListener() {
@Override
public void onHandshakeSuccess(SocketAddress address, ProxyClient client, ServerInfo serverInfo) {
synchronized (results) {
results.put(address, serverInfo);
}
doneLatch.countDown();
}
@Override
public void onHandshakeFailure(SocketAddress address, ProxyClient client, Throwable cause) {
}
};
TestHostProvider rs = new TestHostProvider();
ProxyClientManager clientManager = createProxyClientManager(builder, rs, 0L);
clientManager.registerProxyListener(listener);
assertEquals("There should be no clients in the manager", 0, clientManager.getNumProxies());
for (int i = 0; i < numHosts; i++) {
rs.addHost(createSocketAddress(initialPort + i));
}
// handshake would handshake with 3 hosts again
clientManager.handshake();
doneLatch.await();
assertEquals("Handshake should return server info", numHosts, results.size());
assertTrue("Handshake should get all server infos", Maps.difference(serverInfoMap, results).areEqual());
}
Aggregations