quarkus: Mutiny and Resteasy integration sometimes fails with "Attempted to do blocking IO from the IO thread"
Describe the bug
Often Multi returned to Resteasy causes exception, although both database and Kafka are executed in a worker thread.
Code:
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("file-upload")
public Uni<List<Long>> upload(
@Nonnull @Context SecurityContext securityContext,
Map<String, byte[]> files
) {
return Multi
.createFrom().iterable(files.entrySet())
.onItem().produceMulti(entry -> extractFiles(securityContext.getUserPrincipal().getName(), entry))
.concatenate()
.onItem().invoke(fileEntity -> persist(fileEntity)).subscribeOn(Infrastructure.getDefaultWorkerPool())
.emitOn(Infrastructure.getDefaultWorkerPool())
.onItem().produceCompletionStage(fileEntity -> sendMessage(fileEntity)).concatenate()
.collectItems().asList()
.ifNoItem().after(Duration.ofSeconds(200)).failWith(
() -> new ServerErrorException("Kafka not responding", Response.Status.GATEWAY_TIMEOUT));
}
sendMessage returns CompletableFuture:
final CompletableFuture<Void> voidCompletableFuture = new CompletableFuture();
OutgoingKafkaRecord<Long, ProcessingStatus> message =
KafkaRecord.of(fileEntity.getId(), status)
.withAck(() -> {
voidCompletableFuture.complete(null);
return voidCompletableFuture;
});
emitter.send(message);
return voidCompletableFuture.thenApply(void -> status.getId());
Exception:
[vert.x-eventloop-thread-2] [SynchronousDispatcher.java:545] - RESTEASY002020: Unhandled asynchronous exception, sending back 500: javax.ws.rs.ProcessingException: RESTEASY008205: JSON Binding serialization error java.lang.IllegalStateException: UT000126: Attempted to do blocking IO from the IO thread. This is prohibited as it may result in deadlocks
It seems that error does not happen when emmiter.send is used without the future.
Expected behavior
Resteasy should just execute the request as all blocking operations are moved to worker threads.
Actual behavior
Resteasy complaints about blocking operation.
To Reproduce Steps to reproduce the behavior:
- Return Multi with emmiter.send waiting for future to complete
Configuration
# Add your application.properties here, if applicable.
Screenshots (If applicable, add screenshots to help explain your problem.)
Environment (please complete the following information):
- Output of
uname -aorver: Microsoft Windows [Version 10.0.19041.153] - Output of
java -version: 1.8 - GraalVM version (if different from Java):
- Quarkus version or git rev: 1.3.0.Final
- Build tool (ie. output of
mvnw --versionorgradlew --version): Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Additional context @cescoffier https://groups.google.com/forum/#!topic/smallrye/J4fEeQYfM5w
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 32 (18 by maintainers)
@akoufa yiu can use ‘Infrastructure.getDefaultExecutor()’
Yeah, i see the gzip interceptor which forces blocking IO.