-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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 basic observable constructor tests #42219
Add basic observable constructor tests #42219
Conversation
There are no reviewers for this pull request. Please reach out on the chat room to get help with this. Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments, nothing too serious. The biggest concern I have is .closed
which I don't think was discussed in the explainer repo at all. I'd prefer to leave that out here and address it there first to collect more feedback and thoughts if you're OK with that. In part because its utility is not 100% clear to me, so having that discussion outside of this test PR seems good.
subscriber.next(1); | ||
throw error; | ||
} finally { | ||
assert_true(subscriber.closed, "subscriber is closed after error"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, we haven't really discussed the .closed
attribute on the Subscriber
interface yet, so maybe we should hold off on this assertion. Can we assert other side-effects, (i.e., would subscriber.signal.aborted
be true? Maybe not since the outer AbortController didn't actually abort this).
Maybe it would just be good to assert the teardown is called, and talk about this attribute later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(i.e., would subscriber.signal.aborted be true? Maybe not since the outer AbortController didn't actually abort this).
There's some "dead space" where there's a difference between "closed" and "signal.aborted"
Basically, the signal is aborted after your complete
handler is fired. But at the moment subscriber.complete
is called, the subscriber has to be shut down (closed
).
Consider the following: (this may seem outlandish, but it's just a small bit of code simulating some of the things that can happen with home brew observable operators, in particular, reentrancy, where someone composes an observable that emits into itself in a roundabout way)
let level = 0;
const source = new Observable(subscriber => {
subscriber.addTeardown(() => {
console.log('torn down!');
});
if (level++ === 0) {
// Rentrant code
source.subscribe({
complete: () => {
if ((!subscriber.signal.aborted) {
subscriber.complete();
}
},
signal: subscriber.signal
})
} else {
subscriber.complete();
}
})
const ac = new AbortController();
source.subscribe({
complete: () => console.log('complete!'),
signal: ac.signal
})
In the above case, the provided subscriber.signal
, which is following whatever signal was passed into the subscribe
call, would not be "aborted" yet, because it should semantically abort AFTER the complete
handler fires. So we'll get stuck in a loop.
There's already a pieces of state we have to track internally in the Subscriber
so that next
, error
, and complete
can't be called if error
or complete
have already been called. This is an important part of the guarantee.
So the lifecycle inside the subscriber (if complete
or error
is called):
- "close" the subscriber to new calls/actions (disable
next
, report errors passed toerror
, disablecomplete
, and putaddTeardown
in a state of "execute immediately". This is a safety mechanism and a valuable guarantee. - emit
complete
(orerror
) - Tear down (by aborting the signal attached to this, which also controls everything registed with
addTeardown
.
The closed
property of Subscriber
exposes this "close" state from 1 above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that makes sense, I just think we should put this in the explainer with a PR first, with the justification above etc. Also I think it's worth having some discussion about:
In the above case, the provided subscriber.signal, which is following whatever signal was passed into the subscribe call, would not be "aborted" yet, because it should semantically abort AFTER the complete handler fires.
It sounds like you're saying that even with .closed
existing, you think the AbortSignal should be aborted after complete()
or error()
is fired, which seems weird to me. I think only AbortController should be able to abort an AbortSignal. But maybe you're only saying this in the theoretical world where .closed
didn't exist (like the example you have above)... either way, all of this discussion should probably happen on https://github.com/WICG/observable instead of here, if that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we'll get stuck in a loop.
This part I'm not sure I see. It seems like the re-entrant (i.e., the most nested) call to complete()
would just trigger the outermost complete()
handler, right? I don't think I see an actual infinite loop here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you think the AbortSignal should be aborted after complete() or error() is fired, which seems weird to me. I think only AbortController should be able to abort an AbortSignal
There's the AbortSignal that was passed into the subscription, and then there's an AbortSignal related to the status of the subscription. If the subscription is "complete" or "errors" we need to teardown resources and cancel any upcoming work. Therefor, if you complete()
or error()
the signal
that is on the Subscriber
should be aborted. This signal would not be the same signal that was passed into the subscription.
new Observable(subscriber => {
console.log(subscriber.signal.aborted); // false
subscriber.complete();
console.log(subscriber.signal.aborted); // true.
})
}); | ||
|
||
source.subscribe(); | ||
}, "subscriber is closed after complete"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the above comment about .closed
. It isn't totally clear to me what this buys us, so maybe we could discuss it on the explainer before writing test expectations around it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
closed
is necessary for "synchronous firehose" scenarios. If you want take
to work in this scenario:
const result = new Observable(subscriber => {
let n = 0;
while (!subscriber.closed) {
subscriber.next(n++);
}
})
result.take(3).subscribe({
next: console.log
})
If there's no way to examine if the subscription has been ended by the take(3)
, then there's no way to break that while
loop.
source.subscribe(); | ||
}, "subscriber is closed after complete"); | ||
|
||
test(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
"should emit values synchronously, but not error after complete" | ||
); | ||
|
||
assert_true(errorReported); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the error reporting handler be called twice? And if so, should we assert that one way or another?
This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. This passes a few more tests in #42219, but is very limited because we don't actually add the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97
This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from #42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97
This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from #42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97
This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from web-platform-tests/wpt#42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonf@chromium.org> Commit-Queue: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1205647}
This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from #42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonf@chromium.org> Commit-Queue: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1205647}
This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from #42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonf@chromium.org> Commit-Queue: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1205647}
This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from web-platform-tests#42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonf@chromium.org> Commit-Queue: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1205647}
…nctionality, a=testonly Automatic update from web-platform-tests DOM: Add Observable SubscribeCallback functionality This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from web-platform-tests/wpt#42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonf@chromium.org> Commit-Queue: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1205647} -- wpt-commits: b213cbfd9c0cad9a3cf2005a57194fefac1b9b64 wpt-pr: 42341
…nctionality, a=testonly Automatic update from web-platform-tests DOM: Add Observable SubscribeCallback functionality This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from web-platform-tests/wpt#42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonf@chromium.org> Commit-Queue: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1205647} -- wpt-commits: b213cbfd9c0cad9a3cf2005a57194fefac1b9b64 wpt-pr: 42341
…nctionality, a=testonly Automatic update from web-platform-tests DOM: Add Observable SubscribeCallback functionality This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from web-platform-tests/wpt#42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: benbenlesh.com R=masonfchromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonfchromium.org> Commit-Queue: Dominic Farolino <domchromium.org> Cr-Commit-Position: refs/heads/main{#1205647} -- wpt-commits: b213cbfd9c0cad9a3cf2005a57194fefac1b9b64 wpt-pr: 42341 UltraBlame original commit: 0b36f23073b503e392372b6ba718cb32fe4c7d13
…nctionality, a=testonly Automatic update from web-platform-tests DOM: Add Observable SubscribeCallback functionality This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from web-platform-tests/wpt#42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: benbenlesh.com R=masonfchromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonfchromium.org> Commit-Queue: Dominic Farolino <domchromium.org> Cr-Commit-Position: refs/heads/main{#1205647} -- wpt-commits: b213cbfd9c0cad9a3cf2005a57194fefac1b9b64 wpt-pr: 42341 UltraBlame original commit: 0b36f23073b503e392372b6ba718cb32fe4c7d13
…nctionality, a=testonly Automatic update from web-platform-tests DOM: Add Observable SubscribeCallback functionality This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from web-platform-tests/wpt#42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: benbenlesh.com R=masonfchromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonfchromium.org> Commit-Queue: Dominic Farolino <domchromium.org> Cr-Commit-Position: refs/heads/main{#1205647} -- wpt-commits: b213cbfd9c0cad9a3cf2005a57194fefac1b9b64 wpt-pr: 42341 UltraBlame original commit: 0b36f23073b503e392372b6ba718cb32fe4c7d13
913263b
to
5b5df24
Compare
7178afd
to
0598389
Compare
This CL adds the SubscribeCallback type and invokes it when the subscribe method is called. It also adds some rudimentary `Observable` constructor tests that were ported from web-platform-tests#42219 into this CL. The results are very limited because we haven't introduced the `Subscriber` interface yet, or the corresponding `Observer` dictionary event handlers. Those will come in another CL. For now, this just implements the Observable subscription invocation semantics as well as the report exception semantics. For WPTs: Co-authored-by: ben@benlesh.com R=masonf@chromium.org Bug: 1485981 Change-Id: Id32a21ed943908e3a2e61d50261a1b4b3fbd5e97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4904686 Reviewed-by: Mason Freed <masonf@chromium.org> Commit-Queue: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1205647}
Attn @domfarolino ... here's a basic battery of tests covering
new Observable
, observation semantics, handled and unhandled errors in various scenarios,addTeardown
,subscribe
andforEach
.