Skip to content

Commit 050a0c3

Browse files
committed
Disable the removed auto-read managing handler
To make sure it does not influence the auto-read status of the channel. Also restore default value of auto-read for channel when such handler is removed. This change is needed to avoid removing a handler that has just disabled auto-read. This is possible when handler receives a RECORD that causes it to disable auto-read and then receives a SUCCESS message, which causes it to be dequeued with auto-read being disabled.
1 parent 78cf1e3 commit 050a0c3

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcher.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,11 @@ private void ackFailureIfNeeded()
265265
private ResponseHandler removeHandler()
266266
{
267267
ResponseHandler handler = handlers.remove();
268-
if ( autoReadManagingHandler == handler )
268+
if ( handler == autoReadManagingHandler )
269269
{
270-
// handler that is being removed is the auto-read managing handler
270+
// the auto-read managing handler is being removed
271271
// make sure this dispatcher does not hold on to a removed handler
272-
autoReadManagingHandler = null;
272+
updateAutoReadManagingHandler( null );
273273
}
274274
return handler;
275275
}
@@ -278,15 +278,20 @@ private void updateAutoReadManagingHandlerIfNeeded( ResponseHandler handler )
278278
{
279279
if ( handler instanceof AutoReadManagingResponseHandler )
280280
{
281-
if ( autoReadManagingHandler != null )
282-
{
283-
// there already exists a handler that manages channel's auto-read
284-
// make it stop because new managing handler is being added and there should only be a single such handler
285-
autoReadManagingHandler.disableAutoReadManagement();
286-
// restore the default value of auto-read
287-
channel.config().setAutoRead( true );
288-
}
289-
autoReadManagingHandler = (AutoReadManagingResponseHandler) handler;
281+
updateAutoReadManagingHandler( (AutoReadManagingResponseHandler) handler );
290282
}
291283
}
284+
285+
private void updateAutoReadManagingHandler( AutoReadManagingResponseHandler newHandler )
286+
{
287+
if ( autoReadManagingHandler != null )
288+
{
289+
// there already exists a handler that manages channel's auto-read
290+
// make it stop because new managing handler is being added and there should only be a single such handler
291+
autoReadManagingHandler.disableAutoReadManagement();
292+
// restore the default value of auto-read
293+
channel.config().setAutoRead( true );
294+
}
295+
autoReadManagingHandler = newHandler;
296+
}
292297
}

driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcherTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import static org.junit.Assert.assertTrue;
4545
import static org.junit.Assert.fail;
4646
import static org.mockito.Matchers.any;
47+
import static org.mockito.Matchers.anyBoolean;
4748
import static org.mockito.Matchers.eq;
4849
import static org.mockito.Mockito.inOrder;
4950
import static org.mockito.Mockito.mock;
@@ -503,6 +504,25 @@ public void shouldForgetAutoReadManagingHandlerWhenItIsRemoved()
503504
assertNull( dispatcher.autoReadManagingHandler() );
504505
}
505506

507+
@Test
508+
public void shouldReEnableAutoReadWhenAutoReadManagingHandlerIsRemoved()
509+
{
510+
Channel channel = newChannelMock();
511+
InboundMessageDispatcher dispatcher = newDispatcher( channel );
512+
513+
AutoReadManagingResponseHandler handler = mock( AutoReadManagingResponseHandler.class );
514+
dispatcher.enqueue( handler );
515+
assertEquals( handler, dispatcher.autoReadManagingHandler() );
516+
verify( handler, never() ).disableAutoReadManagement();
517+
verify( channel.config(), never() ).setAutoRead( anyBoolean() );
518+
519+
dispatcher.handleSuccessMessage( emptyMap() );
520+
521+
assertNull( dispatcher.autoReadManagingHandler() );
522+
verify( handler ).disableAutoReadManagement();
523+
verify( channel.config() ).setAutoRead( anyBoolean() );
524+
}
525+
506526
private static void verifyFailure( ResponseHandler handler )
507527
{
508528
ArgumentCaptor<Neo4jException> captor = ArgumentCaptor.forClass( Neo4jException.class );

0 commit comments

Comments
 (0)