I've spent some time trying various approaches here, and I've come to the conclusion that the status quo is good, actually.
The status quo:
EventBuffer: a vector of timestamped events, with utilities for registering with a Client and fetching subsets of events (e.g. CommandStarted).
EventSubscriber: a streaming view of events in an EventBuffer, with utilities for watching for events matching predicates.
Some approaches I've tried to boil this down to a single unified handler:
Remove EventSubscriber entirely, convert all tests using it to check assumptions post-facto. This would be an enormous amount of work and there are quite a few tests that (subjectively) are easier to follow with the streaming approach. Also, some tests use values from earlier events in subsequent test logic.
Remove EventSubscriber, provide a pop method to pull events from the beginning of the buffer to replace streaming. Along with the readability issues of the above, this makes it harder to reason about and validate the total state of the buffer without maintaining a parallel copy.
Remove EventSubscriber, move its methods to EventBuffer and have them accept a Cursor that tracks the index and return a new Cursor where relevant. This just makes things worse; the two views on the data are still there but the distinction is less clear, and dealing with passing the Cursor around is a hassle.
Remove EventSubscriber, move its methods to EventBuffer using an internal cursor. This has the same obfuscation issues as above; additionally, various tests spawn multiple EventSubscribers from a single EventBuffer which can't be easily expressed with them merged.
My position now is that buffering and streaming are both reasonable views of events generated during a span of action and which is more natural for a given test will depend quite a bit on the particulars. What I've done in this PR is (hopefully) clarify that distinction and how it should be used:
Rename EventSubscriber (and related methods/bindings) to EventStream. "Subscriber" was reflective of the old implementation using a broadcast channel and linked subscribers; now that it's iterating over a buffer, I think "stream" is a clearer reflection of the core "one at a time" nature.
Remove EventBuffer::watch_all, which I originally wrote hoping that it would be a replacement for EventSubscriber but turned out to be too awkward to use in practice.
Update documentation to make recommended usage clear (and remove obsolete mentions of broadcast/subscription).
RUST-1425
I've spent some time trying various approaches here, and I've come to the conclusion that the status quo is good, actually.
The status quo:
EventBuffer
: a vector of timestamped events, with utilities for registering with aClient
and fetching subsets of events (e.g.CommandStarted
).EventSubscriber
: a streaming view of events in anEventBuffer
, with utilities for watching for events matching predicates.Some approaches I've tried to boil this down to a single unified handler:
EventSubscriber
entirely, convert all tests using it to check assumptions post-facto. This would be an enormous amount of work and there are quite a few tests that (subjectively) are easier to follow with the streaming approach. Also, some tests use values from earlier events in subsequent test logic.EventSubscriber
, provide apop
method to pull events from the beginning of the buffer to replace streaming. Along with the readability issues of the above, this makes it harder to reason about and validate the total state of the buffer without maintaining a parallel copy.EventSubscriber
, move its methods toEventBuffer
and have them accept aCursor
that tracks the index and return a newCursor
where relevant. This just makes things worse; the two views on the data are still there but the distinction is less clear, and dealing with passing theCursor
around is a hassle.EventSubscriber
, move its methods toEventBuffer
using an internal cursor. This has the same obfuscation issues as above; additionally, various tests spawn multipleEventSubscribers
from a singleEventBuffer
which can't be easily expressed with them merged.My position now is that buffering and streaming are both reasonable views of events generated during a span of action and which is more natural for a given test will depend quite a bit on the particulars. What I've done in this PR is (hopefully) clarify that distinction and how it should be used:
EventSubscriber
(and related methods/bindings) toEventStream
. "Subscriber" was reflective of the old implementation using a broadcast channel and linked subscribers; now that it's iterating over a buffer, I think "stream" is a clearer reflection of the core "one at a time" nature.EventBuffer::watch_all
, which I originally wrote hoping that it would be a replacement forEventSubscriber
but turned out to be too awkward to use in practice.