Skip to content
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

Handle thread interruption by closing the channel #441

Merged
merged 4 commits into from
Dec 13, 2017

Conversation

lutovich
Copy link
Contributor

@lutovich lutovich commented Dec 1, 2017

Blocking API like Session#run() is now implemented on top of async API, i.e. Session#runAsync(). Blocking calls simply invoke async ones and uninterruptibly wait for them to complete. Previously, with blocking IO, thread interruptions resulted in ClosedByInterruptException which terminated query/transaction in a harsh way. Right now interrupts will do nothing. Handling them is not strictly required because Thread#interrupt() is not a nice thing to do. However, interrupts are still used in some environments as a last resort thing.

This commit makes driver react on thread interrupts by closing the underlying Netty channel. It's only done in places where channel is actually available. Closing of channel results in exception and the waiting thread fails. It will also make database reset state for this connection, terminate transaction and query.

Such approach seems very similar to the previous one except it will result in ServiceUnavailableException instead of ClosedByInterruptException.

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.

Changes look good to me!

@lutovich
Copy link
Contributor Author

Added a commit with some more tests. @ali-ince could you please take a look?

}
catch ( Exception ignore )
{
// expected
Copy link
Contributor

Choose a reason for hiding this comment

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

@lutovich Would it be better to expect a ServiceUnavailableException here instead of a IllegalStateException?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's true. What do you think about always wrapping exceptions from connectivity verification in ServiceUnavailableException? (unless it's already a ServiceUnavailableException)

@lutovich
Copy link
Contributor Author

@ali-ince exceptions should now be fixed

@lutovich lutovich force-pushed the 1.5-thread-interrupt branch 2 times, most recently from ae0ac74 to 7b0c9ef Compare December 13, 2017 16:06
Blocking API like `Session#run()` is now implemented on top of async
API, i.e. `Session#runAsync()`. Blocking calls simply invoke async
ones and uninterruptibly wait for them to complete. Previously, with
blocking IO, thread interruptions resulted in
`ClosedByInterruptException` which terminated query/transaction in a
harsh way. Right now interrupts will do nothing. Handling them is not
strictly required because `Thread#interrupt()` is not a nice thing
to do. However, interrupts are still used in some environments as a
last resort thing.

This commit makes driver react on thread interrupts by closing the
underlying Netty channel. It's only done in places where channel is
actually available. Closing of channel results in exception and
the waiting thread fails. It will also make database reset state
for this connection, terminate transaction and query.

Such aproach seems very similar to the previous one except it will
result in `ServiceUnavailableException` instead of
`ClosedByInterruptException`.
Added couple more integrations tests to verify that `Thread#interrupt()`
terminates active connection and "unblocks" the blocking thread:
  * when driver is created towards unresponsive server
  * when transaction blocks to read back the result
  * when transaction blocks to commit

Also `NettyConnection` will now fail provided handlers except throwing
exception directly. Increased test coverage for future helpers.
Driver verifies connectivity on creation. It closes the connection pool
when thread is interrupted. Previously original `IllegalStateException`
from the closed pool has been propagated to the user.

This commit makes connectivity verification always throw
`ServiceUnavailableException`.
Also added unit tests for `Futures#asCompletionException()`.
@ali-ince ali-ince merged commit cfbff4a into neo4j:1.5 Dec 13, 2017
@lutovich lutovich deleted the 1.5-thread-interrupt branch December 14, 2017 09:13
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