-
Notifications
You must be signed in to change notification settings - Fork 155
Prohibit blocking operations in IO threads #434
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
Conversation
There was a problem hiding this 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 along with a couple of comments.
public final class EventLoopGroupFactory | ||
{ | ||
private static final String THREAD_NAME_PREFIX = "Neo4jDriverIO"; | ||
private static final int THREAD_PRIORITY = Thread.MAX_PRIORITY; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should stick with Thread.NORM_PRIORITY
. Maybe we can depend on a system property to override the default, if such a requirement arises.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MAX_PRIORITY
is what netty uses inside. Here I'm basically duplicating default behaviour just to create threads of our own class. Such thread can then be easily detected with simple instanceof
.
@@ -1028,6 +1029,65 @@ public void shouldPropagateFailureFromFirstIllegalQuery() | |||
assertEquals( 0, countNodesByLabel( "Node3" ) ); | |||
} | |||
|
|||
@Test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we shall also add some more task chaining tests that mixes up sync / async usage with successful completion i.e. making use of thenApplyAsync
to make chained task to be run in another executor? It may be good to address this kind of usage in the docs.
a20ef2e
to
738f37a
Compare
@ali-ince added unit test to check that created event loop threads are the same as default ones created by netty and couple tests with blocking operations in |
This commit makes blocking operations like `Session#run()` throw `IllegalStateException` when executed by Netty event loop IO thread. It's needed because blocking operations are implemented on top of async operations, they simply wait for `Future` to complete by calling `Future#get()`. For example `session.run("CREATE ()")` delegates to `session#runAsync("CREATE ()")` and waits for it to complete. Blocking operation in IO thread might result in this thread waiting for itself to read from network. This will result in deadlocks. Users should avoid calling blocking API methods when chaining `CompletionStage`s returned from async API methods. All operations within a single chain of `CompletionStage` should be async.
Production code uses unbounded `Futures#blockingGet()` that ignores interrupts and waits until task completes. This is not desired in tests because we do not expect async calls to take long time there. Commit makes all tests use bounded wait from `TestUtil` class instead.
* to verify that created event loop threads are the same as default Netty event loop threads * to verify that it's possible to execute blocking operations in `ForkJoinPool.commonPool()` when chaining async stages
738f37a
to
cc29ca7
Compare
No description provided.