question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Rest-client-mutiny issue, exhausting thread pool

See original GitHub issue

Describe the bug

When using rest-client-mutiny, returning a Uni, it starts failing after configured pool size is exhausted, default appeared to be 50. quarkus.rest-client.config-key.connection-pool-size=5

connect-timeout,read-timeout,connection-ttl variables don’t affect the result. Sometimes, it manages to do “yet another round” of requests, so if pool-size is N, it appear to get 2*N working.

My workaround for now is set scope=RequestScoped, this issue is reproducible with Singleton, Dependent and ApplicationScoped scopes.

Expected behavior

I was expecting to manage infinite sequencial requests with the pool.

Actual behavior

It does not manage infinite requests, they are silently hanging.

When stopped the service, this is the error we get on each of the hanging threads

{
  "class": "java.util.concurrent.ThreadPoolExecutor$AbortPolicy",
  "method": "rejectedExecution",
  "line": 2065
},
{
  "class": "java.util.concurrent.ThreadPoolExecutor",
  "method": "reject",
  "line": 833
},
{
  "class": "java.util.concurrent.ScheduledThreadPoolExecutor",
  "method": "delayedExecute",
  "line": 340
},
{
  "class": "java.util.concurrent.ScheduledThreadPoolExecutor",
  "method": "schedule",
  "line": 562
},
{
  "class": "io.quarkus.mutiny.runtime.MutinyInfrastructure$2",
  "method": "schedule",
  "line": 54
},
{
  "class": "io.smallrye.mutiny.operators.uni.UniDelayOnItem$UniDelayOnItemProcessor",
  "method": "onItem",
  "line": 54
},
{
  "class": "io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription",
  "method": "forward",
  "line": 38
},
{
  "class": "io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription",
  "method": "access$100",
  "line": 26
},
{
  "class": "io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem",
  "method": "subscribe",
  "line": 23
},
{
  "class": "io.smallrye.mutiny.operators.AbstractUni",
  "method": "subscribe",
  "line": 36
},
{
  "class": "io.smallrye.mutiny.operators.uni.UniDelayOnItem",
  "method": "subscribe",
  "line": 28
},
{
  "class": "io.smallrye.mutiny.operators.AbstractUni",
  "method": "subscribe",
  "line": 36
},
{
  "class": "io.smallrye.mutiny.converters.uni.UniToMultiPublisher$UniToMultiSubscription",
  "method": "request",
  "line": 74
},
{
  "class": "io.smallrye.mutiny.operators.multi.MultiFlatMapOp$FlatMapInner",
  "method": "onSubscribe",
  "line": 601
},
{
  "class": "io.smallrye.mutiny.converters.uni.UniToMultiPublisher",
  "method": "subscribe",
  "line": 26
},
{
  "class": "io.smallrye.mutiny.groups.MultiCreate$1",
  "method": "subscribe",
  "line": 163
},
{
  "class": "io.smallrye.mutiny.operators.multi.MultiFlatMapOp$FlatMapMainSubscriber",
  "method": "onItem",
  "line": 193
},
{
  "class": "io.smallrye.mutiny.subscription.MultiSubscriber",
  "method": "onNext",
  "line": 61
},
{
  "class": "io.smallrye.mutiny.operators.multi.processors.UnicastProcessor",
  "method": "drainWithDownstream",
  "line": 103
},
{
  "class": "io.smallrye.mutiny.operators.multi.processors.UnicastProcessor",
  "method": "drain",
  "line": 134
},
{
  "class": "io.smallrye.mutiny.operators.multi.processors.UnicastProcessor",
  "method": "onNext",
  "line": 200
},
{
  "class": "io.smallrye.mutiny.operators.multi.processors.SerializedProcessor",
  "method": "onNext",
  "line": 105
},
{
  "class": "io.smallrye.mutiny.subscription.SerializedSubscriber",
  "method": "onItem",
  "line": 75
},
{
  "class": "io.smallrye.mutiny.subscription.MultiSubscriber",
  "method": "onNext",
  "line": 61
},
{
  "class": "io.smallrye.mutiny.operators.multi.MultiRetryWhenOp$RetryWhenOperator",
  "method": "onFailure",
  "line": 129
},
{
  "class": "io.smallrye.mutiny.subscription.MultiSubscriber",
  "method": "onError",
  "line": 73
},
{
  "class": "io.smallrye.mutiny.converters.uni.UniToMultiPublisher$UniToMultiSubscription",
  "method": "onFailure",
  "line": 103
},
{
  "class": "io.smallrye.mutiny.operators.uni.UniOperatorProcessor",
  "method": "onFailure",
  "line": 54
},
{
  "class": "io.smallrye.mutiny.operators.uni.UniOperatorProcessor",
  "method": "onFailure",
  "line": 54
},
{
  "class": "io.smallrye.mutiny.operators.uni.UniOperatorProcessor",
  "method": "onFailure",
  "line": 54
},
{
  "class": "io.smallrye.mutiny.operators.uni.UniOnItemConsume$UniOnItemComsumeProcessor",
  "method": "onFailure",
  "line": 65
},
{
  "class": "io.smallrye.mutiny.operators.uni.UniOperatorProcessor",
  "method": "onFailure",
  "line": 54
},
{
  "class": "io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage$CompletionStageUniSubscription",
  "method": "forwardResult",
  "line": 58
},
{
  "class": "java.util.concurrent.CompletableFuture",
  "method": "uniWhenComplete",
  "line": 863
},
{
  "class": "java.util.concurrent.CompletableFuture$UniWhenComplete",
  "method": "tryFire",
  "line": 841
},
{
  "class": "java.util.concurrent.CompletableFuture",
  "method": "postComplete",
  "line": 510
},
{
  "class": "java.util.concurrent.CompletableFuture$AsyncSupply",
  "method": "run",
  "line": 1773
},
{
  "class": "org.jboss.resteasy.microprofile.client.impl.MpClientInvocation$Decorator",
  "method": "lambda$decorate$0",
  "line": 93
},
{
  "class": "io.smallrye.context.impl.wrappers.SlowContextualRunnable",
  "method": "run",
  "line": 19
},
{
  "class": "io.quarkus..core.runtime.VertxCoreRecorder$14",
  "method": "runWith",
  "line": 555
},
{
  "class": "org.jboss.threads.EnhancedQueueExecutor$Task",
  "method": "run",
  "line": 2449
},
{
  "class": "org.jboss.threads.EnhancedQueueExecutor$ThreadBody",
  "method": "run",
  "line": 1478
},
{
  "class": "org.jboss.threads.DelegatingRunnable",
  "method": "run",
  "line": 29
},
{
  "class": "org.jboss.threads.ThreadLocalResettingRunnable",
  "method": "run",
  "line": 29
},
{
  "class": "io.netty.util.concurrent.FastThreadLocalRunnable",
  "method": "run",
  "line": 30
},
{
  "class": "java.lang.Thread",
  "method": "run",
  "line": 833
},
{
  "class": "com.oracle.svm.core.thread.PlatformThreads",
  "method": "threadStartRoutine",
  "line": 704
},
{
  "class": "com.oracle.svm.core.posix.thread.PosixPlatformThreads",
  "method": "pthreadStartRoutine",
  "line": 202
}```

### How to Reproduce?

Library is deprecated, if you think there is any chance you fix it, I will create a reproducer.
I am not expecting a fix, just reporting it and maybe letting me know if I am doing something wrong...

My code is returning Uni<Void>:
 @RestClient
private final SomeClient client; 
 .....
Uni<Void> .... {
....
   client.sendResult(getAuthorizationHeader(), parameter,  entity)
                    .replaceWithVoid()
                    .invoke(logWebhookSent(entity));

}


### Output of `uname -a` or `ver`

_No response_

### Output of `java -version`

17.0.1

### GraalVM version (if different from Java)

22.2

### Quarkus version or git rev

2.14.0.Final

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

gradle 7.5.1

### Additional information

We started using mutiny instead of reactive because we needed this PR merged to use it https://github.com/quarkusio/quarkus/issues/27901

Issue Analytics

  • State:open
  • Created 10 months ago
  • Comments:11 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
Chexpircommented, Nov 16, 2022

@cescoffier I will create one as soon as I have a short-term fix for my project and put it here.

0reactions
cescoffiercommented, Nov 28, 2022

If you use the reactive REST client, the issue does not happen. So, it’s a bug in the classic REST client. Unfortunately, I won’t be able to help on this one.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Concurrent asynchronous actions with Mutiny - Quarkus
In a non-reactive approach, both calls would block the caller thread, and, except if you use a worker thread pool, the calls are...
Read more >
Diagnosing thread pool exhaustion issues in .NET Core apps
In this episode, Software Engineer, Mike Rousos, joins Rich to go through some ways to diagnose thread pool exhaustion in your .NET apps....
Read more >
Building a Reactive polling mechanism with SmallRye Mutiny ...
We will be using the reactive Rest Client from Quarkus which makes use of the Vertx. event I/O thread. It produces a single...
Read more >
quarkus reactive mutiny thread pool management
This is very good question! The return type of a RESTEasy Reactice endpoint does not have any effect on which thread the endpoint...
Read more >
Quarkus Versions - Open Source Agenda
#28069 - Fix some minor issues in rabbitmq-reference.adoc ... #27166 - Connection pool exhaustion for lazy entity association (acquisition timeout) ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found