Skip to content

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

Merged
merged 3 commits into from
Nov 24, 2017

Conversation

lutovich
Copy link
Contributor

No description provided.

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 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;
Copy link
Contributor

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.

Copy link
Contributor Author

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
Copy link
Contributor

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.

@lutovich lutovich force-pushed the 1.5-no-block-in-evt-loop branch from a20ef2e to 738f37a Compare November 23, 2017 10:57
@lutovich
Copy link
Contributor Author

@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 #thenXXXAsync

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
@lutovich lutovich force-pushed the 1.5-no-block-in-evt-loop branch from 738f37a to cc29ca7 Compare November 23, 2017 21:45
@zhenlineo zhenlineo merged commit b92eac3 into neo4j:1.5 Nov 24, 2017
@lutovich lutovich deleted the 1.5-no-block-in-evt-loop branch November 24, 2017 12:45
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.

3 participants