use of java.util.concurrent.Semaphore in project databus by linkedin.
the class TestNettyHttpDatabusBootstrapConnection method testServerBootstrapDisconnect.
@Test
public /**
* This is a unit test for DDSDBUS-3537. There is a lag between a network channel disconnect and the
* state change in AbstractNettyHttpConnection. This can cause a race condition in various requestXXX objects which
* check the state of the connection using the network channel. As a result, they may attempt to reconnect while
* AbstractNettyHttpConnection is still in CONNECTED state which causes an error for an incorrect transition
* CONNECTED -> CONNECTING.
*
* The test simulates the above condition by injecting a handler in the client pipeline which artificially holds up
* the channelClosed message. As a result we can inject a request while the netty channel is disconnected but the
* AbstractNettyHttpConnection object has not detected this yet.
*/
void testServerBootstrapDisconnect() throws Exception {
final Logger log = Logger.getLogger("TestNettyHttpDatabusBootstrapConnection.testServerBootstrapDisconnect");
log.info("starting");
log.info("setup the client");
TestingConnectionCallback callback = TestingConnectionCallback.createAndStart("testServerSourcesDisconnect");
DummyRemoteExceptionHandler remoteExceptionHandler = new DummyRemoteExceptionHandler();
final NettyHttpDatabusBootstrapConnection conn = (NettyHttpDatabusBootstrapConnection) CONN_FACTORY.createConnection(BOOTSTRAP_SERVER_INFO, callback, remoteExceptionHandler);
try {
log.info("initial setup");
final List<String> sourceNamesList = Arrays.asList(SOURCE1_NAME);
final Checkpoint cp = Checkpoint.createOnlineConsumptionCheckpoint(0);
BootstrapCheckpointHandler cpHandler = new BootstrapCheckpointHandler(sourceNamesList);
cpHandler.createInitialBootstrapCheckpoint(cp, 0L);
final DummyDatabusBootstrapConnectionStateMessage bstCallback = new DummyDatabusBootstrapConnectionStateMessage(log);
log.info("process a normal startSCN which should establish the connection");
sendStartScnHappyPath(conn, cp, bstCallback, SOURCE1_NAME, 100L, log);
Assert.assertTrue(conn.isConnected());
//wait for the response
TestUtil.assertWithBackoff(new ConditionCheck() {
@Override
public boolean check() {
return null != bstCallback.getCheckpoint();
}
}, "wait for /startSCN response", 100, log);
log.info("verify /startSCN response");
final Checkpoint startScnCp = bstCallback.getCheckpoint();
Assert.assertNotNull(startScnCp);
Assert.assertEquals(100L, startScnCp.getBootstrapStartScn().longValue());
log.info("instrument the client pipeline so that we can intercept and delay the channelClosed message");
final Semaphore passMessage = new Semaphore(1);
final CountDownLatch closeSent = new CountDownLatch(1);
passMessage.acquire();
conn._channel.getPipeline().addBefore("handler", "closeChannelDelay", new SimpleChannelHandler() {
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
closeSent.countDown();
passMessage.acquire();
try {
super.channelClosed(ctx, e);
} finally {
passMessage.release();
}
}
});
final Channel serverChannel = getServerChannelForClientConn(conn);
Thread asyncChannelClose = new Thread(new Runnable() {
@Override
public void run() {
log.info("closing server channel");
serverChannel.close();
log.info("server channel: closed");
closeSent.countDown();
}
}, "asyncChannelCloseThread");
asyncChannelClose.setDaemon(true);
Thread asyncBootstrapReq = new Thread(new Runnable() {
@Override
public void run() {
conn.requestStream("1", null, 10000, startScnCp, bstCallback);
}
}, "asyncBootstrapReqThread");
asyncBootstrapReq.setDaemon(true);
log.info("simultaneously closing connection and sending /bootstrap request");
bstCallback.reset();
asyncChannelClose.start();
Assert.assertTrue(closeSent.await(1000, TimeUnit.MILLISECONDS));
TestUtil.assertWithBackoff(new ConditionCheck() {
@Override
public boolean check() {
return !conn._channel.isConnected();
}
}, "waiting for disconnect on the client side", 1000, log);
Assert.assertEquals(AbstractNettyHttpConnection.State.CONNECTED, conn.getNetworkState());
log.info("asynchronously sending /bootstrap");
asyncBootstrapReq.start();
log.info("letting channelClose get through");
TestUtil.assertWithBackoff(new ConditionCheck() {
@Override
public boolean check() {
return bstCallback.isStreamRequestError();
}
}, "wait for streamRequestError callback", 1000, log);
passMessage.release();
log.info("finished");
} finally {
conn.close();
callback.shutdown();
log.info("cleaned");
}
}
use of java.util.concurrent.Semaphore in project hazelcast by hazelcast.
the class ClientMapReduceTest method testAsyncMapper.
@Test(timeout = 120000)
public void testAsyncMapper() throws Exception {
Config config = buildConfig();
HazelcastInstance h1 = hazelcastFactory.newHazelcastInstance(config);
HazelcastInstance h2 = hazelcastFactory.newHazelcastInstance(config);
HazelcastInstance h3 = hazelcastFactory.newHazelcastInstance(config);
assertClusterSizeEventually(3, h1);
assertClusterSizeEventually(3, h2);
assertClusterSizeEventually(3, h3);
HazelcastInstance client = hazelcastFactory.newHazelcastClient();
IMap<Integer, Integer> m1 = client.getMap(randomString());
for (int i = 0; i < 100; i++) {
m1.put(i, i);
}
final Map<String, List<Integer>> listenerResults = new HashMap<String, List<Integer>>();
final Semaphore semaphore = new Semaphore(1);
semaphore.acquire();
JobTracker tracker = client.getJobTracker("default");
Job<Integer, Integer> job = tracker.newJob(integerKvSource(m1));
ICompletableFuture<Map<String, List<Integer>>> future = job.mapper(new TestMapper()).submit();
future.andThen(new ExecutionCallback<Map<String, List<Integer>>>() {
@Override
public void onResponse(Map<String, List<Integer>> response) {
listenerResults.putAll(response);
semaphore.release();
}
@Override
public void onFailure(Throwable t) {
semaphore.release();
}
});
semaphore.acquire();
assertEquals(100, listenerResults.size());
for (List<Integer> value : listenerResults.values()) {
assertEquals(1, value.size());
}
}
use of java.util.concurrent.Semaphore in project hazelcast by hazelcast.
the class ClientMapReduceTest method testAsyncMapperReducerCollator.
@Test(timeout = 120000)
public void testAsyncMapperReducerCollator() throws Exception {
Config config = buildConfig();
HazelcastInstance h1 = hazelcastFactory.newHazelcastInstance(config);
HazelcastInstance h2 = hazelcastFactory.newHazelcastInstance(config);
HazelcastInstance h3 = hazelcastFactory.newHazelcastInstance(config);
assertClusterSizeEventually(3, h1);
assertClusterSizeEventually(3, h2);
assertClusterSizeEventually(3, h3);
HazelcastInstance client = hazelcastFactory.newHazelcastClient();
IMap<Integer, Integer> m1 = client.getMap(randomString());
for (int i = 0; i < 100; i++) {
m1.put(i, i);
}
final int[] result = new int[1];
final Semaphore semaphore = new Semaphore(1);
semaphore.acquire();
JobTracker tracker = client.getJobTracker("default");
Job<Integer, Integer> job = tracker.newJob(integerKvSource(m1));
ICompletableFuture<Integer> future = job.mapper(new GroupingTestMapper()).reducer(new TestReducerFactory()).submit(new TestCollator());
future.andThen(new ExecutionCallback<Integer>() {
@Override
public void onResponse(Integer response) {
result[0] = response.intValue();
semaphore.release();
}
@Override
public void onFailure(Throwable t) {
semaphore.release();
}
});
// Precalculate result
int expectedResult = 0;
for (int i = 0; i < 100; i++) {
expectedResult += i;
}
semaphore.acquire();
for (int i = 0; i < 4; i++) {
assertEquals(expectedResult, result[0]);
}
}
use of java.util.concurrent.Semaphore in project hazelcast by hazelcast.
the class ClientMultiMapReduceTest method testAsyncMapperCollator.
@Test(timeout = 120000)
public void testAsyncMapperCollator() throws Exception {
Config config = buildConfig();
HazelcastInstance h1 = hazelcastFactory.newHazelcastInstance(config);
HazelcastInstance h2 = hazelcastFactory.newHazelcastInstance(config);
HazelcastInstance h3 = hazelcastFactory.newHazelcastInstance(config);
assertClusterSizeEventually(3, h1);
assertClusterSizeEventually(3, h2);
assertClusterSizeEventually(3, h3);
HazelcastInstance client = hazelcastFactory.newHazelcastClient();
MultiMap<Integer, Integer> m1 = client.getMultiMap(randomString());
for (int i = 0; i < 100; i++) {
m1.put(i / 2, i);
}
final int[] result = new int[1];
final Semaphore semaphore = new Semaphore(1);
semaphore.acquire();
JobTracker tracker = client.getJobTracker("default");
Job<Integer, Integer> job = tracker.newJob(integerKvSource(m1));
ICompletableFuture<Integer> future = //
job.mapper(new GroupingTestMapper()).submit(new GroupingTestCollator());
future.andThen(new ExecutionCallback<Integer>() {
@Override
public void onResponse(Integer response) {
result[0] = response.intValue();
semaphore.release();
}
@Override
public void onFailure(Throwable t) {
semaphore.release();
}
});
// Precalculate result
int expectedResult = 0;
for (int i = 0; i < 100; i++) {
expectedResult += i;
}
semaphore.acquire();
for (int i = 0; i < 4; i++) {
assertEquals(expectedResult, result[0]);
}
}
use of java.util.concurrent.Semaphore in project hazelcast by hazelcast.
the class DistributedMapperClientMapReduceTest method testAsyncMapperReducerCollator.
@Test(timeout = 120000)
public void testAsyncMapperReducerCollator() throws Exception {
Config config = buildConfig();
HazelcastInstance h1 = hazelcastFactory.newHazelcastInstance(config);
HazelcastInstance h2 = hazelcastFactory.newHazelcastInstance(config);
HazelcastInstance h3 = hazelcastFactory.newHazelcastInstance(config);
assertClusterSizeEventually(3, h1);
assertClusterSizeEventually(3, h2);
assertClusterSizeEventually(3, h3);
HazelcastInstance client = hazelcastFactory.newHazelcastClient(null);
IMap<Integer, Integer> m1 = client.getMap(randomString());
for (int i = 0; i < 100; i++) {
m1.put(i, i);
}
final int[] result = new int[1];
final Semaphore semaphore = new Semaphore(1);
semaphore.acquire();
JobTracker tracker = client.getJobTracker("default");
Job<Integer, Integer> job = tracker.newJob(integerKvSource(m1));
ICompletableFuture<Integer> future = job.mapper(new GroupingTestMapper()).combiner(new TestCombinerFactory()).reducer(new TestReducerFactory()).submit(new TestCollator());
future.andThen(new ExecutionCallback<Integer>() {
@Override
public void onResponse(Integer response) {
try {
result[0] = response.intValue();
} finally {
semaphore.release();
}
}
@Override
public void onFailure(Throwable t) {
semaphore.release();
}
});
// Precalculate result
int expectedResult = 0;
for (int i = 0; i < 100; i++) {
expectedResult += i;
}
semaphore.acquire();
for (int i = 0; i < 4; i++) {
assertEquals(expectedResult, result[0]);
}
}
Aggregations