executeBlocking in worker thread

416 views
Skip to first unread message

Nat

unread,
Jul 10, 2015, 5:34:23 PM7/10/15
to ve...@googlegroups.com
From the code, it looks like executeBlocking will be executed by another thread instead of executed inline if the code is called from the worker thread. Wouldn't it be more reasonable to execute it inline to avoid deadlock in case that the worker thread pool is fully utilized?

Tim Fox

unread,
Jul 11, 2015, 1:48:13 AM7/11/15
to ve...@googlegroups.com
Not sure I follow, could you provide some more detail on this please?


On 10/07/15 22:34, Nat wrote:
From the code, it looks like executeBlocking will be executed by another thread instead of executed inline if the code is called from the worker thread. Wouldn't it be more reasonable to execute it inline to avoid deadlock in case that the worker thread pool is fully utilized?
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Francesco Cina

unread,
Jul 14, 2015, 4:49:20 AM7/14/15
to ve...@googlegroups.com
Good point. I think Nat is right.

It could happen that (simplified scenario):
- ThreadPool has only one Thread
- the code block running in the Thread performs a call to executeBlocking
- Deadlock because no available Threads to execute the executeBlocking

With the proposal of Nat this will never happen if the executeBlocking call is executed in the same Thread of its blockink caller.

Tim Fox

unread,
Jul 14, 2015, 4:55:07 AM7/14/15
to ve...@googlegroups.com
Could you explain the point? I was awaiting clarification from Nat, but if you understand it then perhaps you could share? :)
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.

Francesco Cina

unread,
Jul 14, 2015, 6:46:56 AM7/14/15
to ve...@googlegroups.com
I guess that Nat is suggesting that if a portion of code is currently running in a worker Thread and it executes another blocking action through the executeBlocking() method, then this last blocking action could be executed in the current worker thread instead of a new one.

Nat

unread,
Jul 14, 2015, 12:51:35 PM7/14/15
to ve...@googlegroups.com

Thanks, Francesco. That's correct. This happens a lot if you don't have enough number of workers. The scenario is 

1. you have a thread worker-thread-1 to process the executeBlocking call.
2. you invoke executeBlocking call
3. inside executeBlocking call, you try to open a file via vert.fileSystem().openBlocking()
4. worker-thread-1 will block on waiting for openBlocking. However, openBlocking is waiting for worker-thread-1 to be available for execution.

Tim Fox

unread,
Jul 14, 2015, 1:00:17 PM7/14/15
to ve...@googlegroups.com
Can you create a reproducer?

Nat

unread,
Jul 14, 2015, 2:38:30 PM7/14/15
to ve...@googlegroups.com
I misinterpreted executeBlocking() a little bit. It looks like you can only cause a deadlock if you intentionally keep holding the thread like the following:

VertxOptions o = new VertxOptions().setWorkerPoolSize(1);
Vertx vertx = Vertx.vertx(o);
CompletableFuture<Void> t = new CompletableFuture<>();
vertx.executeBlocking(x1 -> {
System.out.println(Thread.currentThread() + ": Execute1");
vertx.executeBlocking(y1 -> {
System.out.println(Thread.currentThread() + ": Execute2");
t.complete(null);
System.out.println(Thread.currentThread() + ": Executed2");
}
, y2 -> System.out.println("Done2"));
System.out.println(Thread.currentThread() + ": Executed1");
t.join();
}, z -> System.out.println("Done1"));

You will see the following output:

Thread[vert.x-worker-thread-0,5,main]: Execute1
Thread[vert.x-worker-thread-0,5,main]: Executed1

"vert.x-worker-thread-0@1013" prio=5 tid=0x16 nid=NA waiting
  java.lang.Thread.State: WAITING
 at sun.misc.Unsafe.park(Unsafe.java:-1)
 at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
 at java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1685)
 at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3320)
 at java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1721)
 at java.util.concurrent.CompletableFuture.join(CompletableFuture.java:1926)
 at Main.lambda$main$2(Main.java:20)
 at Main$$Lambda$2.614685048.handle(Unknown Source:-1)
 at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$14(ContextImpl.java:279)
 at io.vertx.core.impl.ContextImpl$$Lambda$4.1375995437.run(Unknown Source:-1)
 at io.vertx.core.impl.OrderedExecutorFactory$OrderedExecutor.lambda$new$161(OrderedExecutorFactory.java:91)
 at io.vertx.core.impl.OrderedExecutorFactory$OrderedExecutor$$Lambda$1.1205555397.run(Unknown Source:-1)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at java.lang.Thread.run(Thread.java:745)

Tim Fox

unread,
Jul 15, 2015, 2:33:06 AM7/15/15
to ve...@googlegroups.com
Well, you only have one worker thread, so if you're already using that one, and try to execute another blocking action, then clearly that's not going to get executed until the worker is free.

I'd say that's a clear case of expected behaviour :)

Mumuney Abdlquadri

unread,
Jul 15, 2015, 7:10:59 AM7/15/15
to ve...@googlegroups.com
I guess you don't need to wrap code in executeBlocking() in a Worker
Verticle. Vertx already knows you are blocking. Except I am not
getting it right.
> https://groups.google.com/d/msgid/vertx/55A5FE9E.6080108%40gmail.com.
Reply all
Reply to author
Forward
0 new messages