-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Cancel scheduled timeout work, if no longer needed #2135
Changes from 5 commits
9441def
9763c03
6d4937f
a219c6c
0de6ef5
b4d0605
8513fd2
2e2fb9d
9c0a8c9
b31438d
9e16f48
e14c7b8
cfaa876
44ab561
bb8c64e
e29fcdb
119e0d4
fc86e5e
5a2901d
ad27711
24de734
aef558e
39f4009
f38a27e
db72756
ad7dd69
2b66fc4
0bbfdf2
dc568da
d59d733
74dd235
b1bb0ce
42a886a
790a469
0f2522d
94bee5d
c9994b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -139,4 +139,27 @@ describe('Observable.prototype.timeout', () => { | |
expectObservable(result).toBe(expected, values, value); | ||
expectSubscriptions(e1.subscriptions).toBe(e1subs); | ||
}); | ||
|
||
it('should unsubscribe from the scheduled timeout action when timeout is unsubscribed early', () => { | ||
const e1 = hot('--a--b--c---d--e--|'); | ||
const e1subs = '^ ! '; | ||
const expected = '--a--b--c-- '; | ||
const unsub = ' ! '; | ||
|
||
const result = e1 | ||
.lift(function(source) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this test is very straightforward. Perhaps it could be refactored into using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we pair on this? I couldn't figure out how to test this at all, so @trxcllnt came up with this solution and it's still not clear to me how we could do it better. 💃 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Blesh let gives you a handle on the source Observable, but lift gives you a handle to each subscriber. In this case we want to know whether the subscriber did something (canceled its internal scheduled action subscription), so we use lift. textbook use-case for lift. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @trxcllnt ugh.. this is a case where we're abusing the fact that I think we need to find a different way to test this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jayphelps I think the way to test this, and other things like it, would be to add functionality to the TestScheduler so that it tracks the Actions it's created and those Actions can be examined to see at what tick they were cancelled. For now, we can leave these tests in here, but they'll need comments explaining what they're doing and why it works. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We could simply pass an object with a call method. .lift({
call(source) { ... }
}) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Blesh this is exactly why Operator has a call method. In an ideal world an operator would just be a function, but because JS sucks, we've had to make them classes. See RxJava, where Operators are functions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ben is OK with this for now, but wants some inline comments about why we're doing |
||
const timeoutSubscriber = this; | ||
const { action } = timeoutSubscriber; // get a ref to the action here | ||
timeoutSubscriber.add(() => { // because it'll be null by the | ||
if (!action.closed) { // time we get into this function. | ||
throw new Error('TimeoutSubscriber scheduled action wasn\'t canceled'); | ||
} | ||
}); | ||
return source._subscribe(timeoutSubscriber); | ||
}) | ||
.timeout(50, null, rxTestScheduler); | ||
|
||
expectObservable(result, unsub).toBe(expected); | ||
expectSubscriptions(e1.subscriptions).toBe(e1subs); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -260,4 +260,30 @@ describe('Observable.prototype.timeoutWith', () => { | |
expectSubscriptions(e1.subscriptions).toBe(e1subs); | ||
expectSubscriptions(e2.subscriptions).toBe(e2subs); | ||
}); | ||
|
||
it('should unsubscribe from the scheduled timeout action when timeout is unsubscribed early', () => { | ||
const e1 = hot('---a---b-----c----|'); | ||
const e1subs = '^ ! '; | ||
const e2 = cold( '-x---y| '); | ||
const e2subs = ' ^ ! '; | ||
const expected = '---a---b----x-- '; | ||
const unsub = ' ! '; | ||
|
||
const result = e1 | ||
.lift(function(source) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
const timeoutSubscriber = this; | ||
const { action } = timeoutSubscriber; // get a ref to the action here | ||
timeoutSubscriber.add(() => { // because it'll be null by the | ||
if (!action.closed) { // time we get into this function. | ||
throw new Error('TimeoutSubscriber scheduled action wasn\'t canceled'); | ||
} | ||
}); | ||
return source._subscribe(timeoutSubscriber); | ||
}) | ||
.timeoutWith(40, e2, rxTestScheduler); | ||
|
||
expectObservable(result, unsub).toBe(expected); | ||
expectSubscriptions(e1.subscriptions).toBe(e1subs); | ||
expectSubscriptions(e2.subscriptions).toBe(e2subs); | ||
}); | ||
}); |
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.
This change seems unrelated although I agree with 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.
@trxcllnt I believe this is you, cool for me to remove?
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.
as long as it's in a follow up PR that's fine with me. I didn't want to clutter up the PR list with internal config changes that only affect the devs working on the project, but I leave it up to your discretion