Skip to content
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

fix(http): remove unnecessary delay when closing server #2732

Merged
merged 5 commits into from
Oct 4, 2022

Conversation

KhaledSakr
Copy link
Contributor

This conditionally removes the backoff delay when an error happens while accepting connections, if the server is already closed. This fixes the leaking async op encountered in the issue below, that can also be reproduced using the test case added in this PR.

closes #2717

@CLAassistant
Copy link

CLAassistant commented Oct 1, 2022

CLA assistant check
All committers have signed the CLA.

http/server.ts Outdated
acceptBackoffDelay = MAX_ACCEPT_BACKOFF_DELAY;
}

await delay(acceptBackoffDelay);
Copy link
Contributor

@cjihrig cjihrig Oct 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the following sequence still possible?

  1. Server is accepting traffic.
  2. Server enters delay().
  3. Server is closed while delay() is still executing.
  4. Test runner reports leaked op.

I think this could be an improvement, but I don't know that it solves the problem.

Copy link
Contributor Author

@KhaledSakr KhaledSakr Oct 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this should be solvable as well by aborting the delay when closing the server. I gave it a go here. However, I think there is room to improve the test case to not have it depend on the leaking detection AssertionError. Any suggestions?

http/server.ts Outdated
@@ -253,6 +254,8 @@ export class Server {

this.#closed = true;

this.#acceptBackoffDelayAbortController.abort();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it work to do this after the for...of loop a couple lines down?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the change here: d749829

http/server.ts Outdated

if (acceptBackoffDelay >= MAX_ACCEPT_BACKOFF_DELAY) {
acceptBackoffDelay = MAX_ACCEPT_BACKOFF_DELAY;
if (!this.#closed) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change can be reverted with the addition of the abort controller and my previous comment about moving the abort() down.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, that makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the change here: e65d8bc

http/server.ts Outdated
Comment on lines 391 to 393
await delay(acceptBackoffDelay, {
signal: this.#acceptBackoffDelayAbortController.signal,
}).catch((err: unknown) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you avoid mixing async/await with Promise APIs. In other words, make this a try...catch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's reasonable. I made the change here: 4f7ef9c

const handler = () => new Response();
const server = new Server({ port, hostname, handler });
server.listenAndServe();
server.close();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to make the change in this PR if this fixes the original issue, but I still think it would be helpful to be able to await on server.close().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general I think it makes sense, specially if we want to wait until all the pending handlers are resolved. However, I'm not yet comfortable enough with the codebase to make this change and I would prefer to keep it separate.

@KhaledSakr KhaledSakr requested review from cjihrig and removed request for kt3k and bartlomieju October 3, 2022 21:57
Copy link
Contributor

@cjihrig cjihrig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for the contribution!

@cjihrig cjihrig merged commit 385511b into denoland:main Oct 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Leaking async operation after closing server
3 participants