Skip to content

fix(resolve): share response headers with singleflight followers#1389

Merged
jensneuse merged 3 commits intomasterfrom
jensneuse/fix-abstract-check
Feb 18, 2026
Merged

fix(resolve): share response headers with singleflight followers#1389
jensneuse merged 3 commits intomasterfrom
jensneuse/fix-abstract-check

Conversation

@jensneuse
Copy link
Copy Markdown
Member

@jensneuse jensneuse commented Feb 18, 2026

Summary by CodeRabbit

  • New Features

    • Added public APIs to retrieve per-request response context and to get/set deduplication/shared-data callbacks.
    • Enhanced request deduplication to propagate leader HTTP metadata (status, headers) and typed shared data to followers.
  • Tests

    • Added tests validating shared-data and HTTP metadata propagation across deduplicated concurrent requests.

When singleflight deduplication is active, follower requests previously received only the serialized response body from the leader — subgraph response headers (e.g. Cache-Control, custom propagated headers) were silently dropped.

This fix addresses both singleflight mechanisms:

  • Subgraph request singleflight: SingleFlightItem now carries responseHeaders and statusCode from the leader's HTTP call. Followers populate their ResponseContext from these fields, so LoaderHooks.OnFinished receives the correct ResponseInfo.ResponseHeaders for every request.
  • Inbound request singleflight: Two opt-in callbacks (GetDeduplicationData / SetDeduplicationData) on Context allow the cosmo router to extract arbitrary state (e.g. accumulated response headers) from the leader and apply it to each follower before writing the response.

Checklist

  • I have discussed my proposed changes in an issue and have received approval to proceed.
  • I have followed the coding standards of the project.
  • Tests or benchmarks have been added or updated.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 18, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds leader-to-follower deduplication state propagation for single-flight requests: new context callbacks for typed get/set, storage of leader HTTP metadata (status and headers) on single-flight items, propagation of that metadata to follower contexts, and supporting tests. Also exposes a ResponseContext getter from the HTTP client package.

Changes

Cohort / File(s) Summary
HTTP Response Context Retrieval
v2/pkg/engine/datasource/httpclient/nethttpclient.go
Added GetResponseContext(ctx context.Context) *ResponseContext to read an injected ResponseContext from context.
Deduplication Data Callbacks
v2/pkg/engine/resolve/context.go
Added public callback fields GetDeduplicationData func(ctx context.Context) any and SetDeduplicationData func(ctx context.Context, data any), a generic helper SetDeduplicationCallbacks[T any](...) for type-safe wiring, and cleared callbacks in Free().
Inbound single-flight state
v2/pkg/engine/resolve/inbound_request_singleflight.go
Added SharedData any to InflightRequest for leader→follower opaque state; adjusted cancellation return path in GetOrCreate.
Subgraph single-flight state
v2/pkg/engine/resolve/subgraph_request_singleflight.go
Added responseHeaders http.Header and statusCode int fields to SingleFlightItem to carry leader HTTP metadata.
Loader: capture/propagate HTTP metadata
v2/pkg/engine/resolve/loader.go
Leader captures HTTP response metadata (status code and cloned headers) into the leader item after load; followers receive and apply that metadata from the shared item.
Resolver: propagate deduplication data
v2/pkg/engine/resolve/resolve.go
When followers reuse single-flight data, code now calls SetDeduplicationData on follower contexts with leader SharedData, and leaders capture SharedData via GetDeduplicationData before finishing single-flight.
Tests: single-flight header/state propagation
v2/pkg/engine/resolve/resolve_test.go, v2/pkg/engine/resolve/subgraph_request_singleflight_test.go, v2/pkg/engine/resolve/inbound_request_singleflight_test.go
Added tests verifying leader→follower propagation of deduplication shared data and HTTP response body/status/headers; added concurrent follower timeout and leader-error follower tests.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Resolver
    participant Context as RequestContext
    participant InflightMgr as Inflight Manager
    participant HTTP as HTTP Client

    Client->>Resolver: Resolve request (may be follower)
    alt No existing inflight (Leader)
        Resolver->>HTTP: Execute HTTP request
        HTTP-->>Resolver: Response + ResponseContext
        Resolver->>Context: Capture ResponseContext (status, headers)
        Resolver->>InflightMgr: Store leader SharedData/status/headers
    end

    Note over Resolver,InflightMgr: Followers arriving while leader is active

    alt Follower uses single-flight result
        Client->>Resolver: Resolve (follower)
        Resolver->>InflightMgr: Retrieve leader SharedData/status/headers
        InflightMgr-->>Resolver: Return SharedData
        Resolver->>Context: Inject SharedData via SetDeduplicationData
        Resolver-->>Client: Return response using leader's HTTP metadata
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(resolve): share response headers with singleflight followers' directly describes the main objective of the PR: implementing header sharing for singleflight deduplication followers.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jensneuse/fix-abstract-check

Comment @coderabbitai help to get the list of available commands and usage tips.

@jensneuse jensneuse force-pushed the jensneuse/fix-abstract-check branch from 266498a to dc7a163 Compare February 18, 2026 09:48
Subgraph singleflight followers now receive the leader's HTTP response
headers and status code by storing them in SingleFlightItem and
populating the follower's ResponseContext on the way out.

Inbound request singleflight followers now support arbitrary shared data
via two new opt-in callbacks on Context (GetDeduplicationData /
SetDeduplicationData), enabling the cosmo router to propagate response
header state from leader to follower.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jensneuse jensneuse force-pushed the jensneuse/fix-abstract-check branch from dc7a163 to c28d5e1 Compare February 18, 2026 09:50
…sertion

- Clone responseHeaders for each singleflight follower to prevent data
  races when downstream code mutates headers concurrently
- Use comma-ok type assertion in SetDeduplicationCallbacks instead of
  bare assertion that could panic on type mismatch
- Add doc comment on GetResponseContext
- Fix stale line-number reference, add ordering invariant documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jensneuse jensneuse marked this pull request as ready for review February 18, 2026 10:01
…timeout path

Followers that timed out would write their context error to the shared
request.Err field without synchronization, racing with other followers
and the leader's FinishErr. Return ctx.Err() directly instead of
mutating shared state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@StarpTech StarpTech left a comment

Choose a reason for hiding this comment

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

LGTM

@jensneuse jensneuse merged commit ed80a8e into master Feb 18, 2026
11 checks passed
@jensneuse jensneuse deleted the jensneuse/fix-abstract-check branch February 18, 2026 10:23
jensneuse pushed a commit that referenced this pull request Feb 18, 2026
🤖 I have created a release *beep* *boop*
---


##
[2.0.0-rc.251](v2.0.0-rc.250...v2.0.0-rc.251)
(2026-02-18)


### Bug Fixes

* **resolve:** share response headers with singleflight followers
([#1389](#1389))
([ed80a8e](ed80a8e))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed an issue where response headers were not properly shared with
singleflight followers.

---

**Version:** 2.0.0-rc.251

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants