Repository navigation
http2: [8.x] server stream emits error after close #24559
Description
Activity
/cc @nodejs/http2
Reacted by Myles BorinsI've opened a PR with a test for this... gonna start digging
So it would appear that the change that introduced this behavior difference landed in 10.x... as the order is consistent all the way through 9.x.
I believe it is this Semver-Major change to net
As such I think that this behavior difference is expected, and unfortunately not something that can be fixed. I'll let someone else chime in to confirm. Perhaps it makes sense to document this?
/cc @lpinca
Emitting error after close is a bug. In a lot of cases, an hard-to-solve one. I’m inclined to consider this just a bug.
(bugs could be semver-major)
@mcollina are you suggesting we change the behavior in net in 8.x LTS?
No, we should fix http2 everywhere.
I don't think backporting #19241 is an option. It's definitely semver-major.
Reacted by Ali Ijaz Sheikhto add to what @lpinca said... the issue here is not http2 it is net, which I don't think we can change
@MylesBorins I'm proposing we fix http2 to handle this new event ordering correctly. Worst case, we swallow the error. IMHO after
'close'no error should be emitted. This change might be semver-major, but that's a different decision.I agree we should not revert the change in net.
@mcollina I like you proposal. I'm not sure what it means in practice though, wouldn't it make future backports harder or is the plan to apply the changes on master first?
I would apply the changes on master first, and backport as usual.
I haven't digged into this yet but I wonder why a net change should impact the ordering of events on a single http2 stream. The TCP connection (net) is not closed in the use case above.
If there is no issue on master how would you fix something that isn't broken? I mean how do you justify the change?
Oh I misunderstood the issue. Then we should probably work on a fix on Node 8 to address the situation. This is probably going to be very hard.
IMHO it's better than we just swallow the error on Node 8. Unfortunately this is going to make the backports harder.
I did some debugging and I think #19836 is the change which fixed this in Node >= 10.
Yes, it seems it's a combination of these. Also #19451 seems to be involved.
I got following call chain:respondWithFile=>fs.open()==>
afterOpen()=>this.destroy(err)=>this._destroy()NodeJS 8:
ServerHttp2Stream._destroy()callsprocess.nextTick(emit, this, 'close', code)=> close comes first
Callback passed to_destroy()does aprocess.nextTick(emitErrorNT, this, err)NodeJS 10:
Callback passed to_destroy()does aprocess.nextTick(emitErrorAndCloseNT, this, err)==> emits first error then close
==> theprocess.nextTick(emit, this, 'close', code);inServerHttp2Stream._destroy()has been removed in #19451I have a fix in http2 to correct the sequence but I found that v8.x has a test which verifies that
errorcomes afterclose.... This test was adapted in #17406 to verifycloseis aftererror.Edit: PR: #24789
Should I submit a PR to correct the sequence or is this anyway something which can't be done in a patch/minor release?- added a commit that references this issue
on Dec 11, 2018 fixed via #24789
With 8.13.0 http2 server stream emits
errorafterclosewhereas 10.13.0 and 11.2.0 emiterrorbeforeclose.I was expecting that 8.13.0 acts like 10.13.0 as http2 is out of experimental now and quite a lot was backported to reach parity.
The sequence is not documented to my understanding but I have the feeling that
errorshould come first.In my use case (APM) the consequence is that I can't attach the
errorevent to the server transaction as this one is already closed.Reproducer:
prints:
Refs: #22850