quarkus: @Blocking doesn't work
Hi guys.
Describe the bug
@Blocking does not seem to be taken into account when using a reactive call stack.
“”" Annotation used to indicate that the annotated method is inherently blocking and so should not be executed on a non-blockable thread (I/O thread, event loops…) “”"
Expected behavior
Using another thread pool than vertx when @Blocking is detected
Actual behavior
The example of the code logs a WARN because we see a vert.x-eventloop-thread used.
2023-03-08 09:32:42,616 WARN [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 3688 ms, time limit is 2000 ms: io.vertx.core.VertxException: Thread blocked
at java.base@17.0.6/java.lang.Thread.sleep(Native Method)
at org.test.GreetingResource.schedule(GreetingResource.java:39)
at org.test.GreetingResource.hello(GreetingResource.java:26)
at org.test.GreetingResource$quarkusrestinvoker$hello_d1fd18c65b32335d71a4b7282527a960c5fc08f2.invoke(Unknown Source)
at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:114)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:48)
at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:23)
at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:10)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:101)
at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:87)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:140)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
at io.vertx.ext.web.handler.impl.StaticHandlerImpl.lambda$sendStatic$1(StaticHandlerImpl.java:290)
at io.vertx.ext.web.handler.impl.StaticHandlerImpl$$Lambda$959/0x000000080113e208.handle(Unknown Source)
at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
at io.vertx.core.impl.future.FutureBase$$Lambda$936/0x0000000801135c68.run(Unknown Source)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base@17.0.6/java.lang.Thread.run(Thread.java:833)
How to Reproduce?
@ApplicationScoped
public class GreetingResource {
private static final Logger log = LoggerFactory.getLogger(GreetingResource.class);
private final Semaphore semaphore = new Semaphore(1);
@Scheduled(every = "1s")
Uni<Void> everySecond() throws InterruptedException {
schedule();
return Uni.createFrom().voidItem();
}
@Blocking
public void schedule() throws InterruptedException {
log.info("scheduler run new thread");
if (semaphore.tryAcquire(10, SECONDS)) {
log.info("thread in activity");
try {
Thread.sleep(50000);
} finally {
semaphore.release();
}
}
}
}
Output of uname -a
or ver
No response
Output of java -version
openjdk version “17.0.6” 2023-01-17 LTS
OpenJDK Runtime Environment (build 17.0.6+10-LTS)
OpenJDK 64-Bit Server VM (build 17.0.6+10-LTS, mixed mode, sharing)
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.16.4.Final
Build tool (ie. output of mvnw --version
or gradlew --version
)
Apache Maven 3.9.0 (9b58d2bad23a66be161c4664ef21ce219c2c8584)
Maven home: E:\git\scoop\apps\maven\current
Java version: 17.0.6, vendor: BellSoft, runtime: E:\git\scoop\apps\liberica17-full-jdk\current
Default locale: en_US, platform encoding: Cp1252
OS name: “windows 10”, version: “10.0”, arch: “amd64”, family: “windows”
Additional information
Thanks !
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 28 (26 by maintainers)
Ok, so it seems that in the dev mode there are two separate thread pools: core blocking pool (represented by
ExecutorBuildItem
and potentially backed byThreadFactoryBuildItem
) and the worker pool used forVertx.executeBlocking()
. However, in the test and production mode there is a single thread pool used for both the core pool and worker pool.The relevant code can be found in the
io.quarkus.vertx.core.runtime.QuarkusExecutorFactory.createExecutor()
method.@geoand I believe it is the same behavior, even if
@Blocking
is put on the `everySecond()``method. @mpusg can you check?