Skip to content

Ensure a single handler manages channel's auto-read #528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 12, 2018

Conversation

lutovich
Copy link
Contributor

PullAllResponseHandler is responsible for receiving a stream of records. Stream might be very large and handler tries to not fetch if fully into memory. It applies a network-level backpressure by disabling/enabling auto-read property of the underlying Netty channel. This property tells channel to not read from the network. Auto-read is disabled when number of queued records goes beyond the threshold.

Management of auto-read turned out to be problematic for nested queries within a single transaction. Nested queries result in multiple PullAllResponseHandlers being added to the queue of handlers. They will try to manage auto-read concurrently and can sometimes disable it completely. Callers would then be blocked and unable to proceed. This is not a problem for Session#run() because every such call ensures there was a logical SYNC and the previous query has completed and its result is buffered.

This PR fixes a problem by making only a single installed handler manage the channel's auto-read property. Making sure there only exists a single such handler is the responsibility of InboundMessageDispatcher. Auto-read is enabled when new auto-read managing handler is installed. Previous such handler is disabled.

Also renamed InboundMessageDispatcher#queue() to InboundMessageDispatcher#enqueue().

Fixes neo4j/neo4j#12033

@lutovich lutovich requested a review from ali-ince September 10, 2018 11:27
`PullAllResponseHandler` is responsible for receiving a stream of
records. Stream might be very large and handler tries to not fetch
if fully into memory. It applies a network-level backpressure by
disabling/enabling auto-read property of the underlying Netty channel.
This property tells channel to not read from the network. Auto-read is
disabled when number of queued records goes beyond the threshold.

Management of auto-read turned out to be problematic for nested
queries within a single transaction. Nested queries result in
multiple `PullAllResponseHandler`s being added to the queue of
handlers. They will try to manage auto-read concurrently and can
sometimes disable it completely. Callers would then be blocked
and unable to proceed. This is not a problem for `Session#run()`
because every such call ensures there was a logical SYNC and the
previous query has completed and its result is buffered.

This commit fixes a problem by making only a single installed handler
manage the channel's auto-read property. Making sure there only exists
a single such handler is the responsibility of
`InboundMessageDispatcher`. Auto-read is enabled when new auto-read
managing handler is installed. Previous such handler is disabled.
@lutovich lutovich force-pushed the 1.6-tx-with-nested-queries branch from a1504c1 to 5c968ca Compare September 10, 2018 14:16
Copy link
Contributor

@ali-ince ali-ince left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good @lutovich. I only had one comment regarding the cleanup of field autoReadManagingHandler.

Make sure `InboundMessageDispatcher` does not hold on to the last
auto-read management handler after it is removed from the queue of
all handlers.
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.
@lutovich lutovich merged commit b33d284 into neo4j:1.6 Sep 12, 2018
@lutovich lutovich deleted the 1.6-tx-with-nested-queries branch September 12, 2018 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants