Skip to content

Fix Netty 4.1 tracing for pipelined HTTP/1.1 responses - #11937

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 18 commits into
masterfrom
ygree/fix-netty41-http11-pipelining-context-queue
Jul 24, 2026
Merged

Fix Netty 4.1 tracing for pipelined HTTP/1.1 responses#11937
gh-worker-dd-mergequeue-cf854d[bot] merged 18 commits into
masterfrom
ygree/fix-netty41-http11-pipelining-context-queue

Conversation

@ygree

@ygree ygree commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What Does This Do

Fixes Netty 4.1 HTTP/1.1 pipelining by storing server request state in a bounded per-channel FIFO queue instead of a single overwritten channel attribute.

Each queued entry carries the tracing context, captured Accept header, response-analysis state, and any deferred AppSec blocking response. Outbound responses are matched to the correct inbound requests, and request contexts are normally dequeued when the tracing handler observes the final response content.

Full responses complete on their single outbound message because FullHttpResponse implements LastHttpContent. Split responses complete when the terminal LastHttpContent passes through the tracing handler. HEAD, bodyless, and zero-length response headers do not complete a request early. Informational 1xx responses, except WebSocket upgrades, do not start or finish the final response.

The existing mirrored channel context remains available for generic Netty fire* span activation and HTTP/2 multiplex stream-channel propagation.

Motivation

HTTP/1.1 pipelining can place multiple in-flight requests on the same Netty channel. The previous instrumentation kept only one server tracing context per connection, so later requests overwrote earlier request state before their responses were written. This could cause responses to finish or annotate the wrong span.

AppSec blocking responses must also follow pipelined response ordering so that a blocked request cannot overtake an earlier pending response.

Additional Notes

  • HTTP/1.1 responses are matched to request contexts in FIFO order.
  • Deferred AppSec blocking responses are written only after preceding responses complete.
  • CONTEXT_ATTRIBUTE_KEY remains mirrored for generic Netty fire* span activation and HTTP/2 stream-channel context propagation.
  • If the pending request-context limit is reached, pending contexts are closed and server tracing is disabled for that channel, preventing unbounded retention and response misattribution.
  • Per-channel request state is removed on channelInactive.
  • Suppressed outbound writes in Netty 4.0 and 4.1 are logged without rendering the dropped message object.

Contributor Checklist

Jira ticket: [PROJ-IDENT]

@ygree ygree self-assigned this Jul 13, 2026
@ygree ygree added type: bug fix Bug fix inst: netty Netty instrumentation labels Jul 13, 2026
@datadog-datadog-us1-prod

datadog-datadog-us1-prod Bot commented Jul 13, 2026

Copy link
Copy Markdown

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 69.73% (+12.14%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 31ca152 | Docs | Datadog PR Page | Give us feedback!

@dd-octo-sts

dd-octo-sts Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 13.97 s 13.92 s [-0.4%; +1.2%] (no difference)
startup:insecure-bank:tracing:Agent 12.83 s 12.95 s [-1.5%; -0.2%] (maybe better)
startup:petclinic:appsec:Agent 16.30 s 16.75 s [-7.2%; +1.8%] (no difference)
startup:petclinic:iast:Agent 16.79 s 16.87 s [-1.4%; +0.3%] (no difference)
startup:petclinic:profiling:Agent 16.68 s 16.67 s [-1.0%; +1.1%] (no difference)
startup:petclinic:sca:Agent 16.87 s 16.68 s [+0.2%; +2.1%] (maybe worse)
startup:petclinic:tracing:Agent 15.58 s 16.17 s [-7.8%; +0.5%] (no difference)

Commit: 31ca1528 · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@ygree
ygree force-pushed the ygree/fix-netty41-http11-pipelining-context-queue branch from 6f4df04 to 7f7fdf4 Compare July 13, 2026 23:23
@ygree
ygree marked this pull request as ready for review July 14, 2026 00:10
@ygree
ygree requested a review from a team as a code owner July 14, 2026 00:10
@ygree
ygree requested review from jordan-wong and removed request for a team July 14, 2026 00:10

@datadog-datadog-us1-prod datadog-datadog-us1-prod Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datadog Autotest: PASS

More details

The PR correctly fixes HTTP/1.1 pipelining by switching from single-attribute storage to a per-channel queue, allowing multiple in-flight requests to maintain independent tracing contexts. Code review of request queuing, response FIFO matching, error handling, and channel cleanup pathways reveals no behavioral regressions—the fix is architecturally sound.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Datadog Autotest · Commit 7f7fdf4 · What is Autotest? · Any feedback? Reach out in #autotest

@ygree ygree added the tag: ai generated Largely based on code generated by an AI or LLM label Jul 14, 2026
@mcculls
mcculls requested a review from Copilot July 16, 2026 07:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Netty 4.1 HTTP/1.1 pipelined response tracing by tracking per-request server state in a per-channel FIFO queue, so each outbound response is matched to the correct inbound request span/context (including AppSec response blocking state and request header context).

Changes:

  • Introduces ServerRequestContext to queue per-request tracing + AppSec state on the channel and safely disable tracing when backlog grows beyond a limit.
  • Updates Netty 4.1 server handlers to consume/advance this queue when writing responses and when blocking responses.
  • Adds regression tests for HTTP/1.1 pipelining span creation and for the pending-context limit behavior.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
dd-java-agent/instrumentation/netty/netty-common/src/main/java/datadog/trace/instrumentation/netty41/ServerRequestContext.java New per-channel FIFO queue of per-request server tracing/AppSec state for pipelined matching.
dd-java-agent/instrumentation/netty/netty-common/src/main/java/datadog/trace/instrumentation/netty41/AttributeKeys.java Removes now-obsolete per-channel request/response state keys; exposes attributeKey for queue key creation.
dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/MaybeBlockResponseHandler.java Switches AppSec response analysis/blocking bookkeeping to per-request queued context.
dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerResponseTracingHandler.java Finishes/removes the correct request span/context for each response via queued context.
dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java Enqueues per-request context and drains all pending contexts on channel close.
dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java Ensures ServerRequestContext is injected as a helper alongside Netty 4.1 server/client helpers.
dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelHandlerContextInstrumentation.java Adds helper injection for ServerRequestContext and minor refactor in fire* activation.
dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/ChannelFutureListenerInstrumentation.java Adds helper injection for ServerRequestContext in the module helper set.
dd-java-agent/instrumentation/netty/netty-4.1/src/test/java/datadog/trace/instrumentation/netty41/ServerRequestContextTest.java Unit test validating tracing is disabled and contexts are drained when the pending limit is exceeded.
dd-java-agent/instrumentation/netty/netty-4.1/src/test/java/datadog/trace/instrumentation/netty41/server/NettyHttp11PipeliningTest.java Regression test asserting spans are created correctly for pipelined HTTP/1.1 requests/responses.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mcculls

mcculls commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 57f9d65709

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Track server request contexts per pipelined response, snapshot only the
Accept header, and keep AppSec response-block state channel-level so
late streaming chunks are dropped until close.
@ygree

ygree commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@code review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

@vandonr

vandonr commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@codex review

@ygree
ygree requested a review from vandonr July 22, 2026 02:07
@vandonr

vandonr commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88da30a8cd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ygree added 5 commits July 22, 2026 10:27
Defer blocked responses until the active HTTP/1.1 response is complete,
including chunked/streaming responses that finish on LastHttpContent.
Handle header-only responses such as HEAD, 204, 205, 304, and explicit
Content-Length: 0 without requiring an application LastHttpContent.

Also keep interim 1xx responses from completing the server span and add
coverage for chunked, header-only, HEAD, interim, and malformed
Content-Length cases.
Fall back to the mirrored channel context when HTTP/2 stream channels
have no request context queue. Ignore informational responses until the
final response and add regression coverage for response blocking.
@ygree

ygree commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: e1a31f3ee5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ygree

ygree commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 349a4d0054

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@vandonr vandonr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol no issue before merging main, 2 comments afterwards 🙃

anyway, I didn't see issues myself, approving to unblock, I'll let you review the AI's comments if they make sense.

This removes HEAD-specific state, header parsing, and synthetic outbound
messages while making pipelined response attribution follow Netty’s
actual response boundaries.
@ygree
ygree force-pushed the ygree/fix-netty41-http11-pipelining-context-queue branch from f80bce1 to 78ebedf Compare July 23, 2026 17:43
ygree added 3 commits July 23, 2026 12:00
Mark channels when a request block is committed so later pipelined
requests are forwarded to the existing blocking handler and discarded.
Serialize response-function handler installation on the event loop and
clean up partially installed handlers on failure.
Snapshot request metadata before scheduling blocking responses instead
of
retaining and replaying reference-counted HTTP requests.

Reject scheduled blocking responses when their server request context
has
already completed, preventing stale commits from blocking keep-alive
connections.
@ygree
ygree force-pushed the ygree/fix-netty41-http11-pipelining-context-queue branch from 7dd79a7 to b81803e Compare July 23, 2026 21:13
@ygree

ygree commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: b81803e4b6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ygree

ygree commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@gh-worker-devflow-routing-ef8351

gh-worker-devflow-routing-ef8351 Bot commented Jul 24, 2026

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2026-07-24 17:35:56 UTC ℹ️ Start processing command /merge


2026-07-24 17:36:00 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in master is approximately 1h (p90).


2026-07-24 18:26:52 UTC ℹ️ MergeQueue: This merge request was merged

@ygree ygree changed the title Fix Netty 4.1 HTTP/1.1 pipelined response tracing Fix Netty 4.1 tracing for pipelined HTTP/1.1 responses Jul 24, 2026
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot merged commit b994882 into master Jul 24, 2026
592 checks passed
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot deleted the ygree/fix-netty41-http11-pipelining-context-queue branch July 24, 2026 18:26
@github-actions github-actions Bot added this to the 1.65.0 milestone Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

inst: netty Netty instrumentation tag: ai generated Largely based on code generated by an AI or LLM type: bug fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants