jersey icon indicating copy to clipboard operation
jersey copied to clipboard

NettyConnector does not respect timeouts

Open dude-abides opened this issue 1 year ago • 7 comments

I am using Dropwizard 4 (Jersey 3.0.5) on Java 17.

If I make a request, shutdown the server, and make a subsequent request, it hangs despite setting connection timeout to 30s.

dude-abides avatar Apr 10 '24 11:04 dude-abides

You have tried this with 3.0.13, right?

jansupol avatar Apr 10 '24 12:04 jansupol

I just tried with 3.1.6 and 3.0.13, and timeouts are not respected.

dude-abides avatar Apr 10 '24 14:04 dude-abides

I've implemented a test to reproduce the described behavior. Timeout is being set:

protected void configureClient(ClientConfig config) {
        config.property(ClientProperties.READ_TIMEOUT, timeOutValue)
                .connectorProvider(new NettyConnectorProvider());
    }

and instead of the server being shut down, it only runs indefinitely:

while (true) {
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

test expects exception to be thrown:

assertThrows(ProcessingException.class, () -> target(RESOURCE_PATH).request().get());

the TimeoutException is being wrapped with ProcessingException but it's being thrown correctly. How do you define a timeout in the DropWizard?

senivam avatar Apr 26 '24 13:04 senivam

For the timeout issue I was setting connect timeout and read timeout to 60s. I pointed the client at a remote (not localhost) server that was not running. It never connected and never timed out.

dude-abides avatar Apr 26 '24 13:04 dude-abides

if you modify the given test to use connect tiomeout:

protected void configureClient(ClientConfig config) {
        config.property(ClientProperties.CONNECT_TIMEOUT, timeOutValue)
                .connectorProvider(new NettyConnectorProvider());
    }

and the target would be

public WebTarget target(String path) {
        return client().target(String.format("http://8.8.8.8:80", portNumber)).path(path);
    }

the test still fails with the message:

javax.ws.rs.ProcessingException: connection timed out after 9997 ms: /8.8.8.8:80
	at org.glassfish.jersey.netty.connector.NettyConnector.apply(NettyConnector.java:172)
	at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:300)
	at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$0(JerseyInvocation.java:674)
	at org.glassfish.jersey.client.JerseyInvocation.call(JerseyInvocation.java:709)
	at org.glassfish.jersey.client.JerseyInvocation.lambda$runInScope$3(JerseyInvocation.java:703)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:205)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:390)
	at org.glassfish.jersey.client.JerseyInvocation.runInScope(JerseyInvocation.java:703)
	at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:673)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:413)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:313)
	at org.glassfish.jersey.tests.e2e.client.nettyconnector.NettyConnectorTimeoutTest.testNettyConnectorTimeout(NettyConnectorTimeoutTest.java:82)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:194)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
Caused by: io.netty.channel.ConnectTimeoutException: connection timed out after 9997 ms: /8.8.8.8:80
	at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe$1.run(AbstractNioChannel.java:261)
	at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
	at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:153)
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
	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/java.lang.Thread.run(Thread.java:1583)

default connection timeout for the Netty Client is 30s, so if it is not event set, the connection should fail after 30 seconds (I've tested it as well and it behaves so).

senivam avatar Apr 26 '24 13:04 senivam

for the 60s custom timeout Netty Client fails as well:

javax.ws.rs.ProcessingException: connection timed out after 60000 ms: /8.8.8.8:80
	at org.glassfish.jersey.netty.connector.NettyConnector.apply(NettyConnector.java:172)
	at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:300)
	at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$0(JerseyInvocation.java:674)
	at org.glassfish.jersey.client.JerseyInvocation.call(JerseyInvocation.java:709)
	at org.glassfish.jersey.client.JerseyInvocation.lambda$runInScope$3(JerseyInvocation.java:703)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:205)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:390)
	at org.glassfish.jersey.client.JerseyInvocation.runInScope(JerseyInvocation.java:703)
	at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:673)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:413)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:313)
	at org.glassfish.jersey.tests.e2e.client.nettyconnector.NettyConnectorTimeoutTest.testNettyConnectorTimeout(NettyConnectorTimeoutTest.java:82)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:194)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
Caused by: io.netty.channel.ConnectTimeoutException: connection timed out after 60000 ms: /8.8.8.8:80
	at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe$1.run(AbstractNioChannel.java:261)
	at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
	at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:153)
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
	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/java.lang.Thread.run(Thread.java:1583)

senivam avatar Apr 26 '24 13:04 senivam

I will attempt to reproduce when I get a chance.

dude-abides avatar Apr 26 '24 14:04 dude-abides