简体   繁体   中英

Thread Blocked Problem when using Reactive RestEasy with GraphQlClient in QUARKUS

I'm using quarkus version 2.3.0.Final .

I have a rest endpoint in the Controller layer:

    @POST
    @Path("/upload")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Uni<Response> uploadFile(@MultipartForm FormData formData) {

        return documentService.uploadFile(formData).onItem()
                .transform(value -> Response.status(200)
                        .entity(value)
                        .build());
    }

and in the service layer the code


public Uni<?> uploadFile(@NonNull FormData formData) throws Exception {
   // Call to graphQl client using blocking process - the problem occurs here,

   RevisionResponse revisionResponse = entityRepository.createRevision(formData);

   // Do upload to s3 using s3 Async
   return Uni.createFrom()
               .future(
                    storageProviderFactory.getDefaultStorageProvider().upload(formData)))
               .map(storageUploadResponse -> DocumentResponse.builder()
                        .id(revisionResponse.getId())
                        .entityMasterId(revisionResponse.getEntityMasterId())
                        .type(revisionResponse.getType())
                        .path(formData.getFilePath())
                        .description(formData.getDescription())
                        .build());

}

and here are the dependencies that I used:

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-graphql-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-reactive</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-reactive-jsonb</artifactId>
    </dependency>

When I run this function, it's being blocked in entityRepository.createRevision(formData) (The console show the graphql request log but actually, the request even does not hit the target graphql endpoint)

However, if I add the annotation @Blocking in the controller layer, everything works as expected.

I also tried with Uni response for Uni<RevisionResponse> revisionResponse = entityRepository.createRevision(formData); but the same error happens.

Does anyone face these issues, did I config something wrong for the non-blocking processed?

Thank you.

For those who face with the same issue to me, I fix it by wrapping the blocking code with Uni:

Uni<RevisionResponse> revisionResponse = Uni.createForm().item(entityRepository.createRevision(formData));

Ref link: https://smallrye.io/smallrye-mutiny/guides/imperative-to-reactive#running-blocking-code-on-subscription

Because you are returning Uni from your method, RESTEasy Reactive is running the method on the event loop (see this for details). However, it looks like the call to entityRepository.createRevision is blocking IO, which means that the event loop thread is being blocked - something which is not allowed to happen.

Using the @Blocking annotation means that the request is being serviced on a worker pool thread, on which you are allowed to block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM