Mauli
Mauli

Reputation: 17203

Why does Vertx throws a warning even with blocking attribute?

I have a Quarkus application where I use the event bus.

the code in question looks like this:

    @ConsumeEvent(value = "execution-request", blocking = true)
    @Transactional
    @TransactionConfiguration(timeout = 3600)
    public void consume(final Message<ExecutionRequest> msg) {
        try {
            execute(...);
        } catch (final Exception e) {
            // some logging
        }
    }

    private void execute(...)
            throws InterruptedException {
        // it actually runs a long running task, but for 
        // this example this has the same effect
        Thread.sleep(65000);
    }

Why do I still get a

WARN  [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-worker-thread-0,5,main] has been blocked for 63066 ms, time limit is 60000 ms: io.vertx.core.VertxException: Thread blocked

I'm I doing something wrong? Is the blocking parameter at the ConsumeEvent annotation not enough to let that handle in a separate Worker?

Upvotes: 0

Views: 5406

Answers (1)

dano
dano

Reputation: 94881

Your annotation is working as designed; the method is running in a worker thread. You can tell by both the name of the thread "vert.x-worker-thread-0", and by the 60 second timeout before the warnings were logged. The eventloop thread only has a 3 second timeout, I believe.

The default Vert.x worker thread pool is not designed for "very" long running blocking code, as stated in their docs:

Warning:

Blocking code should block for a reasonable amount of time (i.e no more than a few seconds). Long blocking operations or polling operations (i.e a thread that spin in a loop polling events in a blocking fashion) are precluded. When the blocking operation lasts more than the 10 seconds, a message will be printed on the console by the blocked thread checker. Long blocking operations should use a dedicated thread managed by the application, which can interact with verticles using the event-bus or runOnContext

That message mentions blocking for more than 10 seconds triggers a warning, but I think that's a typo; the default is actually 60.

To avoid the warning, you'll need to create a dedicated WorkerExecutor (via vertx.createSharedWorkerExecutor) configured with a very high maxExcecuteTime. However, it does not appear you can tell the @ConsumeEvent annotation to use it instead of the default worker pool, so you'd need to manually create an event bus consumer, as well, or use a regular @ConsumeEvent annotation, but call workerExectur.executeBlocking inside of it.

Upvotes: 3

Related Questions