Uh oh!
There was an error while loading. Please reload this page.
test: re-implement promises.setInterval() test robustly - #37230
Conversation
Trott
commented
Feb 4, 2021
Linkgoron
commented
Feb 4, 2021
If I understand this correctly, this doesn't exactly test what I wanted to check. I wanted to check the following: After 2 iterations, delay the current iteration long enough for the interval to create another value. Then, abort the controller, and see that the value that was created during the previous delay will be read. I believe that this will abort the controller only after the third iteration has already started. |
Trott
commented
Feb 6, 2021
@Linkgoron Ah, I see. OK, I've modified it to use that behavior. Please take a look. I tested it with |
nodejs-github-bot
commented
Feb 6, 2021
nodejs-github-bot
commented
Feb 6, 2021
Linkgoron
commented
Feb 7, 2021
I still think that it isn't exactly what the original test tested. The test is supposed to check that if a value was generated before the controller was aborted and wasn't read yet ("backpressure"), the following call to |
Trott
commented
Feb 7, 2021
@Linkgoron When you say "a value was generated", what do you mean? I thought it meant a value had been generated by the To check what's going on here, I added a logging variable {letfoo='';asyncfunctionrunInterval(fn,intervalTime,signal,emitter){constinput='foobar';constinterval=setInterval(intervalTime,input,{ signal });letiteration=0;foo+='entering for loop\n';forawait(constvalueofinterval){foo+=`got value ${value} from for await\n`;if(emitter){// Next line uses `iteration + 1` because we haven't incremented `iteration` yet.foo+=`emitting the event from iteration ${iteration+1}\n`;emitter.emit('myevent');}assert.strictEqual(value,input);iteration++;foo+=`about to await the passed callback for iteration ${iteration}\n`;awaitfn(iteration);foo+=`finished awaiting the passed callback for iteration ${iteration}\n`;}}{// Check that if we abort when we have some unresolved callbacks,// we actually call them.constcontroller=newAbortController();constmyEvent=newEventEmitter();const{ signal }=controller;constdelay=10;lettotalIterations=0;consttimeoutLoop=runInterval(async(iterationNumber)=>{if(iterationNumber<=2){assert.strictEqual(signal.aborted,false);}if(iterationNumber===2){foo+='adding the once listener in iteration 2\n';myEvent.once('myevent',()=>{foo+='aborting\n';controller.abort();foo+='aborted\n';});}if(iterationNumber>2){assert.strictEqual(signal.aborted,true);}if(iterationNumber>totalIterations){totalIterations=iterationNumber;}},delay,signal,myEvent);timeoutLoop.catch(common.mustCall(()=>{console.log(foo);assert.ok(totalIterations>=3,`iterations was ${totalIterations} < 3`);}));}}The results were this: If I'm understanding correctly, then this appears to be doing the right thing--specifically, this at the end: And if I"m not understanding correctly, are you able to see where I'm getting it wrong? |
Oh, I see the confusion. When I say that a value is generated, I'm talking about the setInterval that's ״running״ in the background "in" the generator. Every time that it's "invoked" (every
The case that the original test was trying to show was what happens if the So, generate the 2nd value -> wait for |
Trott
commented
Feb 7, 2021
Ahhhhhh.... I think I see now. In that case, probably bumping the |
nodejs-github-bot
commented
Feb 7, 2021
Linkgoron
commented
Feb 7, 2021
Yes, that'll work, although you could also do |
Trott
commented
Feb 9, 2021
@nodejs/testing @nodejs/timers This needs a review. |
Trott
commented
Feb 13, 2021
Landed in b4264b5 |
By using events, we can make sure the call to
controller.abort()doesn't happen before the next iteration starts.
Fixes: #37226