Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to replay last N items of a Multi on subscription, or emit something predefined if nothing has been emitted yet #536

Closed
Ladicek opened this issue Apr 29, 2021 · 11 comments · Fixed by #859
Assignees
Labels
enhancement New feature or request on-roadmap The issue is part of the roadmap
Milestone

Comments

@Ladicek
Copy link
Contributor

Ladicek commented Apr 29, 2021

Rx has a concept of BehaviorSubject and ReplayingSubject, which are quite similar and serve a very useful purpose: pre-seed a subscriber with last known value[s] / initial value[s] at the moment of subscription. I think we could unify them under an API like this:

Multi.createBy()
    .replayingAtMost(int)  // buffer size -- to imitate `BehaviorSubject`, use 1
    .withInitialValues(T... or Iterable<T> or perhaps even Multi<T>) // initial values to emit when nothing was emitted yet
    .stream(Multi<T>); // the stream we're wrapping

Calling it replayingAtMost to highlight that if you set 5 items to replay but only 3 items have been emitted, then only 3 will be replayed to a new subscriber. If you think that's intuitive enough, can shorten to just replaying.

WDYT?

@jponge
Copy link
Member

jponge commented May 3, 2021

Do you have any specific use-case in mind?

@Ladicek
Copy link
Contributor Author

Ladicek commented May 3, 2021

I filed this issue as a result of a Gitter discussion starting here: https://gitter.im/smallrye-io/community?at=608a65e5bdc0bc32e6258397

@jponge jponge changed the title add ability to replay last N items of a Multi on subscription, or emit something predefined if nothing has been emitted yet Add ability to replay last N items of a Multi on subscription, or emit something predefined if nothing has been emitted yet May 19, 2021
@jponge jponge self-assigned this Sep 9, 2021
@jponge jponge added this to the 1.2.0 milestone Sep 15, 2021
@jponge jponge added the enhancement New feature or request label Oct 5, 2021
@jponge jponge modified the milestones: 1.2.0, 1.3.0 Nov 18, 2021
@jponge jponge modified the milestones: 1.3.0, 1.4.0 Jan 3, 2022
@jponge
Copy link
Member

jponge commented Jan 13, 2022

I went back thinking about this one.

BehaviorSubject / ReplayingSubject in RxJava are hot streams, so it does make sense to replay items there.

Now Mutiny Multi are cold streams in most cases, so that feature would require turning the wrapped Multi into a hot stream (using . toHotStream()). Depending on the use case one might want to do that... or not 😃 because the first subscriber triggers the source, and then all subscribers will simply join the stream broadcast.

Is it what you had in mind?

@Ladicek
Copy link
Contributor Author

Ladicek commented Jan 13, 2022

Yes. I don't think this feature would make much sense for cold streams, the entire feature implicitly assumes that there's a single broadcast that all subscribers listen to together.

@jponge
Copy link
Member

jponge commented Feb 3, 2022

(notes for myself and the interested reader)

  • I've explored a broken draft where I'd collect items to replay.
  • The first subscriber would make the wrapped multi broadcasting.
  • Each subscriber would be plugged to the concatenation of (i) a stream of the last n items to replay, followed by the broadcasting stream.
  • Aside from questions marks that I have over the behaviour of broadcast (need another issue for that), that approach is subject to items loss between the 2 streams concatenation.
  • We likely need a full replay operator + supporting API here to have fine control over (i) observing events from the wrapped multi, and (ii) ensure that each subscriber gets a proper replay + stream. I would have preferred composing existing operators, but the semantics of replaying while another stream goes on aren't that trivial. But I may be missing something.

@jponge jponge removed this from the 1.4.0 milestone Feb 8, 2022
@jponge
Copy link
Member

jponge commented Mar 2, 2022

So I have something in draft in a scratchpad branch. How does that sound?

  • Multi.createBy().replaying().upTo(3).ofMulti(upstream)
  • Multi.createBy().replaying().ofMulti(upstream)
  • Multi.createBy().replaying().ofSeedAndMulti(seed, upstream) (where seed is an Iterable<T>)
  • Multi.createBy().replaying().upTo(10).ofSeedAndMulti(seed, upstream) (where seed is an Iterable<T>)

@jponge
Copy link
Member

jponge commented Mar 2, 2022

In that branch:

  • upstream becomes a hot-stream (aka subscribed with Long.MAX_VALUE), and
  • subscribers get to replay at their own pace (we honour each subscriber demand at all times)

@Ladicek
Copy link
Contributor Author

Ladicek commented Mar 3, 2022

Do I understand it correctly that the variants without upTo() will [maybe obtain the seed values and then] just join the broadcast? IOW, they are equivalent to upTo(0)?

When I created this issue, I intentionally suggested createBy().replayingAtMost(int) (or, in your parlance, createBy().replayingUpTo(int)) so that you can't skip the number of replayed items. If you didn't want to replay anything, just get the initial values and then join the broadcast, you'd have to say 0 explicitly, which perhaps looks weird, but then using a "replay" feature without actually replaying anything should look weird IMHO :-)

@jponge
Copy link
Member

jponge commented Mar 3, 2022 via email

@Ladicek
Copy link
Contributor Author

Ladicek commented Mar 3, 2022

Ah so it's like upTo(Long.MAX_VALUE), roughly :-) OK, that makes sense.

@jponge
Copy link
Member

jponge commented Mar 3, 2022 via email

jponge added a commit that referenced this issue Mar 7, 2022
Replay a Multi (turned into a hot stream) to multiple (possibly late) subscribers.

See #536 for the initial discussion.
@jponge jponge linked a pull request Mar 7, 2022 that will close this issue
jponge added a commit that referenced this issue Mar 7, 2022
Replay a Multi (turned into a hot stream) to multiple (possibly late) subscribers.

See #536 for the initial discussion.
jponge added a commit that referenced this issue Mar 7, 2022
Replay a Multi (turned into a hot stream) to multiple (possibly late) subscribers.

See #536 for the initial discussion.
@jponge jponge added this to the 1.4.0 milestone Mar 7, 2022
jponge added a commit that referenced this issue Mar 9, 2022
Replay a Multi (turned into a hot stream) to multiple (possibly late) subscribers.

See #536 for the initial discussion.
jponge added a commit that referenced this issue Mar 9, 2022
Replay a Multi (turned into a hot stream) to multiple (possibly late) subscribers.

See #536 for the initial discussion.

Documentation fixes were contributed by:

Co-authored-by: Ladislav Thon <[email protected]>
Co-authored-by: Clement Escoffier <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request on-roadmap The issue is part of the roadmap
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants