-
Notifications
You must be signed in to change notification settings - Fork 76
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
Create streams only after Promise.all() #608
Conversation
Co-authored-by: alxndrsn <alxndrsn> (cherry picked from commit a3a07f6)
Related to #482. This prevents the following sequence: - A stream is created within a Promise.all(). - The stream is to be processed after the Promise.all() is fulfilled. - However, another promise in the Promise.all() is rejected. - As a result, the Promise.all() as a whole is rejected. - As a result, the stream is never processed and isn't destroyed.
@@ -36,8 +37,7 @@ const zipPart = () => { | |||
// if the final component in the pipeline emitted the error, archiver would then | |||
// emit it again, but if it was an intermediate component archiver wouldn't know | |||
// about it. by manually aborting, we always emit the error and archiver never does. | |||
const zipStreamFromParts = (...zipParts) => { | |||
let completed = 0; | |||
const zipStreamFromParts = (...zipPartFns) => { |
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 recommend hiding whitespace when viewing the diff for this file.
resultStream.finalize(); | ||
}); | ||
} | ||
resolve(zipPartFns.shift()()) |
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've marked this PR as a draft while we finish working on #564. |
Closing now that we've decided to close #634. |
Part of a possible solution for #482, copied in part from changes in #564. See the commit message of the fourth commit for notes. The first commit is from #604. I've also cherry-picked from #542 and #553 in order to prevent a conflict with the
master
branch: this PR touches some of the same files as those PRs. When reviewing this PR, I recommend focusing on the fourth commit.What has been done to verify that this works as intended?
In addition to tests, I've deployed this PR to the QA server and followed the reproduction steps in #482. I was successfully able to send 10 concurrent requests. When I sent 11 concurrent requests, one quickly resulted in an error response ("Completely unhandled exception: timeout exceeded when trying to connect"). That is expected given that the maximum number of database connections is 10. However, what's exciting is that after the 11 responses, there was no database connection leak. 🎉
I still want to write a couple more tests to get at the Promise-related behavior of
zipStreamFromParts()
that I've introduced.Why is this the best possible solution? Were any other approaches considered?
I'm actually not sure that this is the best solution or that we want to ship this with v1.5.3. I've created this PR in part so that we can consider this solution further. See #604 (comment) for the three options we've been discussing for v1.5.3.
The main alternative to this solution is a utility function like the one at #482 (comment). In most places, I think this solution is clearer to reason about than what we would get with a utility function. I think the main exception is
zipStreamFromParts()
, which has become more complicated. I also think a utility function could be more performant (though I doubt by much). That said, some of the changes that #564 makes are similar to those here, so we might be heading in this direction for multiple reasons.How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
The hope is that this PR fixes connection leak issues. However, there's a risk of regression with each of the three streaming endpoints that the PR modifies. I think running @alxndrsn's benchmarker against this PR would help us gain confidence.
Does this change require updates to the API documentation? If so, please update docs/api.md as part of this PR.
No changes needed.
Before submitting this PR, please make sure you have:
make test-full
and confirmed all checks still pass OR confirm CircleCI build passes