Skip to content

fix: set sentinel after subscribe to avoid race condition - #41

Merged
cramforce merged 1 commit into
vercel:mainfrom
ken8203:fix/race-condition-sentinel-before-subscribe
Sep 16, 2026
Merged

cramforce merged 1 commit into
vercel:mainfrom
ken8203:fix/race-condition-sentinel-before-subscribe

Conversation

@ken8203

@ken8203 ken8203 commented Jan 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a race condition where consumers could miss the producer's request channel subscription.

Problem

Previously, the sentinel key was set before subscribing to the request channel:

sequenceDiagram
    participant P as Producer
    participant R as Redis
    participant C as Consumer

    P->>R: SET sentinel = "1"
    Note over P: Haven't subscribed yet...
    C->>R: GET sentinel
    R-->>C: "1" (exists)
    C->>R: SUBSCRIBE chunk:listenerId
    C->>R: PUBLISH request:streamId
    Note over R: ❌ No subscriber, message lost!
    P->>R: SUBSCRIBE request:streamId
    Note over P: Too late...
    C--xC: Timeout (1s)
Loading

Solution

Move sentinel set to after the subscribe completes:

sequenceDiagram
    participant P as Producer
    participant R as Redis
    participant C as Consumer

    P->>R: SUBSCRIBE request:streamId
    Note over P: ✅ Subscribe first
    P->>R: SET sentinel = "1"
    Note over P: Then set sentinel
    C->>R: GET sentinel
    R-->>C: "1" (exists)
    C->>R: SUBSCRIBE chunk:listenerId
    C->>R: PUBLISH request:streamId
    R-->>P: Received listenerId
    P->>R: PUBLISH chunk:listenerId
    R-->>C: Received data
    Note over C: ✅ Stream works!
Loading

Changes

  • Moved ctx.publisher.set(sentinel) from createNewResumableStream wrapper to inside the actual function, after ctx.subscriber.subscribe() completes
  • Updated comments to explain the ordering requirement

Testing

All existing tests pass.

@mdnanocom

Copy link
Copy Markdown
Contributor

+1

@mdnanocom

Copy link
Copy Markdown
Contributor

@cramforce are you available for a review here? still having issues in production because of this

@cramforce

Copy link
Copy Markdown
Contributor

Thanks for the mention. Any chance you can add a test?

@mdnanocom

Copy link
Copy Markdown
Contributor

@ken8203

@ken8203

ken8203 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

sure!

@ken8203
ken8203 force-pushed the fix/race-condition-sentinel-before-subscribe branch 2 times, most recently from 6950274 to e05fa54 Compare September 2, 2026 16:24
@ken8203

ken8203 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Hi @cramforce,

I've added a test for the race condition. Please take a look!

@cramforce

Copy link
Copy Markdown
Contributor

Please re-push with signed git

@mdnanocom

mdnanocom commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

@ken8203 can you sign commits?

Previously, the sentinel key was set BEFORE subscribing to the request
channel. This caused a race condition where:

1. Producer sets sentinel
2. Consumer detects sentinel exists
3. Consumer publishes request to request channel
4. Producer subscribes to request channel (TOO LATE - message lost!)

This fix moves the sentinel set to AFTER the subscribe completes:

1. Producer subscribes to request channel
2. Producer sets sentinel
3. Consumer detects sentinel exists
4. Consumer publishes request (SUCCESS - producer receives it)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@ken8203
ken8203 force-pushed the fix/race-condition-sentinel-before-subscribe branch from e05fa54 to 1d49e36 Compare September 8, 2026 13:27
@ken8203

ken8203 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@mdnanocom @cramforce

Hi, I've signed the commits. Please check again!

@mdnanocom

Copy link
Copy Markdown
Contributor

@cramforce are we good here?

@mdnanocom

Copy link
Copy Markdown
Contributor

@cramforce ?

@cramforce
cramforce merged commit dddaeba into vercel:main Sep 16, 2026
4 checks passed
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