Skip to content

Make FromEventBuffered's bufferSize nullable, defaulting to unbounded - #3

Merged
kblok merged 1 commit into
mainfrom
nullable-buffer-size
Jul 29, 2026
Merged

Make FromEventBuffered's bufferSize nullable, defaulting to unbounded#3
kblok merged 1 commit into
mainfrom
nullable-buffer-size

Conversation

@kblok

@kblok kblok commented Jul 29, 2026

Copy link
Copy Markdown
Member

Follow-up to #1/#2's FromEventBuffered and the buffer-size bug it caused in puppeteer-sharp (see hardkoded/puppeteer-sharp#3520).

bufferSize defaulted to 1 — an arbitrary opinion this wrapper had no business holding on its own, and wrong for the method's actual dominant use case: filtering for a specific match among payloads that could arrive in the pre-subscribe gap FromEventBuffered exists to cover. With a buffer of 1, a matching payload can be silently evicted by a later non-matching one before anyone subscribes. Puppeteer-sharp's own WaitForTargetAsync/WaitForFrameAsync hit exactly this — I wrote both, and still fell into it myself, only caught by an external code review.

bufferSize is now int? = null, where null defers entirely to ReplaySubject's own default (unbounded, matching rxjs's own ReplaySubject(bufferSize = Infinity)) instead of FromEventBuffered inventing a second, smaller default of its own. The gap this method targets is normally microseconds — an unbounded buffer is only a real memory concern if a BufferedEventSource stays attached a long time without ever being subscribed to, which a caller can still avoid by passing an explicit bound for that specific usage.

Added a test locking in the new default (multiple pre-subscribe values, all buffered and replayed — not just the last one). All 840 tests pass (839 + 1 new).

🤖 Generated with Claude Code

https://claude.ai/code/session_01K92eapPm8e7mX7puT4cF4s

The 0.1.3 fallout: FromEventBuffered's own default of 1 was an arbitrary opinion this
wrapper had no business holding, and it was wrong for the wrapper's actual dominant use
case (filtering for a specific match among payloads that could arrive in the
pre-subscribe gap this method exists to cover) - even I fell into it myself, in
puppeteer-sharp's own WaitForTargetAsync, before a code review caught it.

bufferSize is now int? = null, where null defers entirely to ReplaySubject's own
default (unbounded, matching rxjs's own ReplaySubject(bufferSize = Infinity)) instead
of inventing a second, smaller opinionated default. The gap this method targets is
normally microseconds; an unbounded buffer only becomes a real memory concern if a
BufferedEventSource stays attached a long time without ever being subscribed to, which
callers can still avoid by passing an explicit bound for that specific usage.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K92eapPm8e7mX7puT4cF4s
@kblok
kblok merged commit b788d3c into main Jul 29, 2026
1 check passed
kblok added a commit to hardkoded/puppeteer-sharp that referenced this pull request Jul 29, 2026
RxSharp 0.1.4 (pending publish - see hardkoded/ReactiveExtensions-Sharp#3) makes
FromEventBuffered's bufferSize nullable, defaulting to ReplaySubject's own unbounded
default instead of an opinionated 1. That's the same guarantee EventBufferSize = 16
was working around locally, so it's redundant now - the safe behavior is just the
library default.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K92eapPm8e7mX7puT4cF4s
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.

1 participant