Optimize the lifecycle of async requests #765
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Async HTTP request work by emitting a "Progress" object to a callback. This object has a "done" flag which, when
true, indicates that all data has been emitting and no future "Progress" objects will be sent.Callers like XHR buffer the response and wait for "done = true" to then process the request.
The HTTP client relies on two important object pools: the connection and the state (with all the buffers for reading/writing).
In its current implementation, the async flow does not release these pooled objects until the final callback has returned. At best, this is inefficient: we're keeping the connection and state objects checked out for longer than they have to be. At worse, it can lead to a deadlock. If the calling code issues a new request when done == true, we'll eventually run out of state objects in the pool.
This commit now releases the state objects before emit the final "done" Progress message. For this to work, this final message will always have null data and an empty header object.