cache(0).put("myKey", "myValue");
// add an interceptor on node B that will block state transfer until we are ready
final CountDownLatch applyStateProceedLatch = new CountDownLatch(1);
final CountDownLatch applyStateStartedLatch = new CountDownLatch(1);
cacheConfigBuilder.customInterceptors().addInterceptor().before(InvocationContextInterceptor.class).interceptor(new CommandInterceptor() {
@Override
protected Object handleDefault(InvocationContext ctx, VisitableCommand cmd) throws Throwable {
// if this 'put' command is caused by state transfer we block until GET begins
if (cmd instanceof PutKeyValueCommand && ((PutKeyValueCommand) cmd).hasFlag(Flag.PUT_FOR_STATE_TRANSFER)) {
// signal we encounter a state transfer PUT
applyStateStartedLatch.countDown();
// wait until it is ok to apply state
if (!applyStateProceedLatch.await(15, TimeUnit.SECONDS)) {
throw new TimeoutException();
}
}
return super.handleDefault(ctx, cmd);
}
});
// add an interceptor on node B that will block GET commands until we are ready
final CountDownLatch getKeyStartedLatch = new CountDownLatch(1);
final CountDownLatch getKeyProceedLatch = new CountDownLatch(1);
cacheConfigBuilder.customInterceptors().addInterceptor().before(CallInterceptor.class).interceptor(new CommandInterceptor() {
@Override
protected Object handleDefault(InvocationContext ctx, VisitableCommand cmd) throws Throwable {
if (cmd instanceof GetKeyValueCommand) {
// signal we encounter a GET
getKeyStartedLatch.countDown();