-
-
Notifications
You must be signed in to change notification settings - Fork 141
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
Should do async stop but did sync stop [edited title] #185
Comments
Hey @whitecolor, I don't know exactly why you are experiencing this issue. Your bin is slightly different than what you have pasted in the description. However, my guess would be that your completion notification is immediate. And this means that between each Here is a snippet demonstrating the two scenarios, and a bin. import xs from 'xstream';
const willRunStartTwice = xs.create({
start: listener => {
console.log( 'starting (probably twice)' );
listener.next();
listener.complete();
},
stop: () => {}
});
const willRunStartOnce = xs.create({
start: listener => {
console.log( 'starting (only once)' );
listener.next();
},
stop: () => {}
});
willRunStartTwice.remember().addListener({ next: () => {} });
willRunStartTwice.remember().addListener({ next: () => {} });
willRunStartOnce.remember().addListener({ next: () => {} });
willRunStartOnce.remember().addListener({ next: () => {} });
willRunStartOnce.remember().addListener({ next: () => {} });
willRunStartOnce.remember().addListener({ next: () => {} });
|
I probably modified it by chance after submitting the issue. Thanks for picking this up. So yes I believe this is the case. |
Hi :) |
This is what I thought, @staltz, but I'd like your guidance on whether or not this really is a violation. Consider our documentation on the question of asynchrony:
What exactly is scheduled to happen asynchronously? The stopping of the producer. And when should that happen? When the last listener leaves. But in the examples we are working with on this issue, I think I had it wrong. This isn't about the number of listeners, this is genuinely about the stream ending. And its completion isn't scheduled to take place in the future (in the examples), so why should the producer's stop callback be scheduled? Consider: const stream = xs.create({
start: listener => {
listener.next();
listener.complete(); // this line doesn't schedule an action, see below
}
}); And the source for completion handling: _c(): void {
const a = this._ils;
const L = a.length;
this._x(); // we definitely end up here
if (this._d) this._dl._c();
if (L == 1) a[0]._c(); else if (L == 0) return; else {
const b = cp(a);
for (let i = 0; i < L; i++) b[i]._c();
}
}
_x(): void { // tear down logic, after error or complete
if (this._ils.length === 0) return;
if (this._prod !== NO) this._prod._stop(); // and we definitely invoke stop
this._err = NO;
this._ils = [];
} So I think the question is different: when a memory stream ends, and a new listener is added, what behavior is expected? Should |
Question: does this issue happen only with remember/MemoryStream? |
In short, no. If you remove the I think that the confusion, the idea that this behavior is buggy comes from the idea that If that is the rule of law, we need to change some code. If it's fine for |
Yeah, so I think this is only about whether MemoryStream should be one-time use or be resetable. There is no correct answer. I've seen this exact issue in RxJS, I recommend reading the discussion: ReactiveX/rxjs#453 Right now, I'm inclined to do what RxJS eventually did: allow reusable MemoryStream. Which means keeping the current behavior, and if you really want MemoryStream to keep the value, then appending it with xs.never().
|
I'm okay with reusable MemoryStream. @whitecolor, is the pattern @staltz identifies acceptable for your use cases? Here is a snippet and bin. import xs from 'xstream';
const example = xs.create({
start: listener => {
console.log( 'starting...' );
listener.next();
listener.complete();
},
stop: () => {}
});
const once$ = xs.merge( example, xs.never() );
once$.addListener({ next: () => {} });
once$.addListener({ next: () => {} });
once$.addListener({ next: () => {} });
once$.addListener({ next: () => {} });
|
Hey @whitecolor, most (okay all) of the bins linked to this seem to have expired, but do the snippets make sense? Does the suggested pattern work for you? |
This is the example of
http
like cycle driver where the request is resolved synchronously. Couldn't narrow it down simple xstream pattern, but I wonder why for one request in sink in this case it actually does two requests (starts stream two times).https://www.webpackbin.com/bins/-Ki1D10ZxL0MfO5pVGQt
The text was updated successfully, but these errors were encountered: