-
Bug
-
Resolution: Done
-
Major
-
3.6.10
-
None
There is a concurrency issue when a user calls messageDispatcher.cast(dests, msg, options, block_for_results, null) and adds a listener later with req.setListener(listener).
If the node installs a new view between cast() and setListener() that removes all the dests nodes, the listener is never called. This test fails:
public void testCastToMissingNode() throws Exception { d1.setRequestHandler(new MyHandler(new byte[10])); b = createChannel(a); b.setName("B"); final CountDownLatch targetLatch = new CountDownLatch(1); d2 = new MessageDispatcher(b, null, null, new RequestHandler() { @Override public Object handle(Message msg) throws Exception { targetLatch.await(); return null; } }); b.connect("MessageDispatcherUnitTest"); Assert.assertEquals(2, b.getView().size()); final CountDownLatch futureLatch = new CountDownLatch(1); FutureListener listener = new FutureListener() { @Override public void futureDone(Future future) { futureLatch.countDown(); } }; List<Address> dests = Collections.singletonList(b.getAddress()); byte[] buf = new byte[1]; Message msg = new Message(); msg.setBuffer(buf); NotifyingFuture<RspList<Object>> future = d1.castMessageWithFuture(dests, msg, RequestOptions.SYNC(), null); b.disconnect(); Thread.sleep(100); future.setListener(listener); assertTrue(futureLatch.await(10, TimeUnit.SECONDS)); targetLatch.countDown(); }
If I change the d1.castMessageWithFuture(dests, msg, RequestOptions.SYNC(), null) with d1.castMessageWithFuture(dests, msg, RequestOptions.SYNC(), listener) and comment out the future.setListener(listener) line, the test passes.
- relates to
-
ISPN-7064 RPC to leaver times out instead of finishing immediately
- Closed