Skip to content

fix(rack): fiber-safe context detachment in EventHandler#2130

Open
rsamoilov wants to merge 1 commit intoopen-telemetry:mainfrom
rage-rb:fix/rack-fiber-safe-context-detachment
Open

fix(rack): fiber-safe context detachment in EventHandler#2130
rsamoilov wants to merge 1 commit intoopen-telemetry:mainfrom
rage-rb:fix/rack-fiber-safe-context-detachment

Conversation

@rsamoilov
Copy link
Copy Markdown

Summary

Fixes context detachment errors in fiber-based environments.

Problem: When using Rack::Events, the on_finish callback can be invoked from a different fiber than on_start (e.g., when streaming response bodies). This causes OpenTelemetry::Context.detach(token) to fail with:

ERROR -- : OpenTelemetry error: calls to detach should match corresponding calls to attach

Solution: Store the fiber reference alongside the token and span. On detach_context:

  • Always finish the span (trace data is never lost)
  • Only detach context if running in the same fiber
  • Log a debug message when detachment is skipped

Note on fiber pooling: Skipping detach could leave stale context in the original fiber. However, servers that reuse fibers across requests would be fundamentally incompatible with any Ruby feature relying on fiber-locals (e.g., ActiveSupport::CurrentAttributes), so this isn't something we should solve at the instrumentation level.

Changes

  • Changed env key from otel.rack.token_and_span to otel.context_info
  • Changed storage format from [token, span] to [fiber, token, span]
  • Updated detach_context to check fiber identity before detaching
  • Applied changes to all three convention variants (stable, old, dup)

Test plan

  • Added unit tests for same-fiber detachment
  • Added unit tests for cross-fiber detachment (verifies span finishes without error)
  • All existing tests pass across all 12 configurations (4 Rack versions × 3 conventions)

Store fiber reference with context token to safely skip detachment
when on_finish is called from a different fiber than on_start.
Spans are always finished regardless of fiber.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@linux-foundation-easycla
Copy link
Copy Markdown

CLA Missing ID CLA Not Signed

One or more co-authors of this pull request were not found. You must specify co-authors in commit message trailer via:

Co-authored-by: name <email>

Supported Co-authored-by: formats include:

  1. Anything <id+login@users.noreply.github.com> - it will locate your GitHub user by id part.
  2. Anything <login@users.noreply.github.com> - it will locate your GitHub user by login part.
  3. Anything <public-email> - it will locate your GitHub user by public-email part. Note that this email must be made public on Github.
  4. Anything <other-email> - it will locate your GitHub user by other-email part but only if that email was used before for any other CLA as a main commit author.
  5. login <any-valid-email> - it will locate your GitHub user by login part, note that login part must be at least 3 characters long.

Alternatively, if the co-author should not be included, remove the Co-authored-by: line from the commit message.

Please update your commit message(s) by doing git commit --amend and then git push [--force] and then request re-running CLA check via commenting on this pull request:

/easycla

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant