From 33cc72c44b04a9f7cc24232f779befbbcccc8f75 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Tue, 15 Sep 2026 11:20:38 +0200 Subject: [PATCH] Prevent Netty idle timers from retaining request context --- ...syncPropagatingDisableInstrumentation.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dd-java-agent/instrumentation/java/java-concurrent/java-concurrent-1.8/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java b/dd-java-agent/instrumentation/java/java-concurrent/java-concurrent-1.8/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java index 7e7d915e0dc..ccc75ed2484 100644 --- a/dd-java-agent/instrumentation/java/java-concurrent/java-concurrent-1.8/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java +++ b/dd-java-agent/instrumentation/java/java-concurrent/java-concurrent-1.8/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java @@ -10,6 +10,8 @@ import static datadog.trace.instrumentation.java.concurrent.ConcurrentInstrumentationNames.EXECUTOR_INSTRUMENTATION_NAME; import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy; import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer; +import static net.bytebuddy.matcher.ElementMatchers.returns; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; import com.google.auto.service.AutoService; @@ -61,6 +63,10 @@ public AsyncPropagatingDisableInstrumentation() { "io.netty.util.concurrent.GlobalEventExecutor", // shaded version "io.grpc.netty.shaded.io.netty.util.concurrent.GlobalEventExecutor"); + private static final ElementMatcher NETTY_IDLE_STATE_HANDLER = + namedOneOf( + "io.netty.handler.timeout.IdleStateHandler", + "io.grpc.netty.shaded.io.netty.handler.timeout.IdleStateHandler"); private static final ElementMatcher JAVA_HTTP_CLIENT = extendsClass(named("java.net.http.HttpClient")); private static final String LETTUCE_HANDSHAKE_HANDLER = @@ -107,6 +113,8 @@ public String[] knownMatchingTypes() { LETTUCE_HANDSHAKE_HANDLER, "io.netty.util.concurrent.GlobalEventExecutor", "io.grpc.netty.shaded.io.netty.util.concurrent.GlobalEventExecutor", + "io.netty.handler.timeout.IdleStateHandler", + "io.grpc.netty.shaded.io.netty.handler.timeout.IdleStateHandler", "com.linecorp.armeria.client.HttpClientFactory", "com.linecorp.armeria.client.HttpChannelPool" }; @@ -215,6 +223,17 @@ public void methodAdvice(MethodTransformer transformer) { isTypeInitializer().and(isDeclaredBy(RXJAVA3_DISABLED_TYPE_INITIALIZERS)), advice); transformer.applyAdvice( isTypeInitializer().and(isDeclaredBy(NETTY_GLOBAL_EVENT_EXECUTOR)), advice); + transformer.applyAdvice( + named("initialize") + .and(returns(void.class)) + .and( + takesArgument( + 0, + namedOneOf( + "io.netty.channel.ChannelHandlerContext", + "io.grpc.netty.shaded.io.netty.channel.ChannelHandlerContext"))) + .and(isDeclaredBy(NETTY_IDLE_STATE_HANDLER)), + advice); transformer.applyAdvice(namedOneOf("sendAsync").and(isDeclaredBy(JAVA_HTTP_CLIENT)), advice); transformer.applyAdvice( named("channelRegistered").and(isDeclaredBy(named(LETTUCE_HANDSHAKE_HANDLER))), advice);