Skip to content

Avoid blocking WithLatestFrom value updates - #2630

Merged
glopesdev merged 1 commit into
bonsai-rx:mainfrom
glopesdev:decouple-withlatestfrom-updates
Jul 6, 2026
Merged

glopesdev merged 1 commit into
bonsai-rx:mainfrom
glopesdev:decouple-withlatestfrom-updates

Conversation

@glopesdev

Copy link
Copy Markdown
Member

WithLatestFrom pairs each source element with the latest value from a second sequence. It was initially built on top of CombineLatest, which serializes both sequences and downstream delivery behind a single lock. With that one lock held for the duration of the downstream OnNext, an incoming element on the value sequence could not refresh the cached latest value until the call returned, so a slow downstream observer would stall the value sequence for as long as it ran. This is common when software-timestamping a data sequence against a high-rate clock, where a slow consumer of the timestamped element stalls the shared clock sequence, blocking its producer so the device input buffer can overflow.

This change reimplements the operator on the two-lock strategy from the current WithLatestFrom in dotnet/reactive. One lock serializes downstream delivery, and a separate lock guards only the cached latest value. The value sequence now updates the cached value under its own lock without waiting on downstream work, so a slow observer delays only further source elements, not value updates.

Validation

Observable behavior is otherwise unchanged. The value sequence is subscribed before the source, so a synchronously available value is ready when the source emits immediately. The source observer forwards completion directly, so the result sequence completes with the source and no longer needs the TakeUntil clause the previous composition added to fix #670. A completed value sequence retains its last value, and an error on either sequence faults downstream.

WithLatestFromTests was added to guard the behavior-preservation dimensions against regression: pairing with the latest value, source completion, value-sequence completion retaining the last value, dropping a source element that arrives before any value, faulting on either sequence, and synchronous value availability.

Closes #2600

Reimplement WithLatestFrom on a two-lock strategy, one gate serializing
downstream delivery and a separate lock guarding only the cached latest
value, so updates from the value sequence no longer wait on downstream
processing of a source element. A slow downstream observer now delays
only further source elements, not refreshes of the latest value, for
example when software-timestamping a data sequence against a high-rate
clock. Observable behavior is otherwise unchanged; the two-lock logic
follows the current dotnet/reactive WithLatestFrom.

Closes bonsai-rx#2600
@glopesdev glopesdev added this to the 2.9.1 milestone Jul 3, 2026
@glopesdev
glopesdev requested a review from a team July 3, 2026 15:26
@glopesdev glopesdev added the fix Pull request that fixes an issue label Jul 3, 2026
@glopesdev
glopesdev merged commit 7b386b8 into bonsai-rx:main Jul 6, 2026
10 checks passed
@glopesdev
glopesdev deleted the decouple-withlatestfrom-updates branch July 6, 2026 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Pull request that fixes an issue

Projects

None yet

1 participant