Skip to content

fix(pool): shared Singleton errors with all waiters#296

Merged
seanmonstar merged 1 commit into
masterfrom
sean/zurvrvwxlrqz
Jun 30, 2026
Merged

fix(pool): shared Singleton errors with all waiters#296
seanmonstar merged 1 commit into
masterfrom
sean/zurvrvwxlrqz

Conversation

@seanmonstar

Copy link
Copy Markdown
Member

Previously, when a bunch of calls to the singleton made a list of waiters, but the underlying service errored making the service, only the first caller would get the underlying error. All the rest of the waiters would just be told the operation was canceled. Which is true, but it made it harder for higher layers to know what to do.

Now, since they are all shared the make call, any error that happens is also shared to all the waiters. We do this by putting the error inside an Arc<dyn std::error::Error> internally, though that exact type isn't exposed. The source chain now properly will show a caller the underlying problem.

Closes hyperium/hyper#4119

cc @aajtodd

@aajtodd

aajtodd commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

I ran the #4119 repro against this branch: waiter outcome goes from 1/8 to 8/8 succeeding, deterministic across 5 runs.

If I'm understanding right, the mechanism for why the waiters recover: on the UseOther bounce, the maker's error is the UseOther sentinel. Propagating it through SingletonError::source() means each waiter's Negotiate future matches it via UseOther::is() and bounces to its own fallback leg. So sharing the error re-arms the existing fallback path for the waiters; no separate re-drive is needed.

This covers the case where the maker's future resolves Err but I don't think it covers the case where the maker's future is dropped before resolving: DitchGuard::drop still resets state to Empty and drops the waiters' senders, so those waiters resolve Canceled. That's the cancel_driver_cancels_all case with the // TODO: cooperative baton refactor comment.

Overall looks good, just one question. Is leaving the maker-dropped path on Canceled intended for this PR or do you have an idea of what that path should look like?

@seanmonstar

Copy link
Copy Markdown
Member Author

Correct, the other case needs the baton passing refactor. I can see about working on that this week.

@seanmonstar seanmonstar merged commit ca6fdbd into master Jun 30, 2026
18 checks passed
@seanmonstar seanmonstar deleted the sean/zurvrvwxlrqz branch June 30, 2026 12:50
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.

Composable pool: coalesced Singleton waiters are canceled when the maker bounces to the fallback leg

2 participants