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

Stop does not properly wait for the server to close #5

Closed
dcherman opened this issue Jan 6, 2019 · 11 comments
Closed

Stop does not properly wait for the server to close #5

dcherman opened this issue Jan 6, 2019 · 11 comments
Labels

Comments

@dcherman
Copy link

dcherman commented Jan 6, 2019

Thanks for providing this lib, I was about to write something like this when I saw you mention this in the k8s slack channel :)

Was looking through the code and noticed that the stop method does not properly wait for the server to close since no callback is provided. Since the method was marked async, it seems like you had intended for it to wait.

@gajus
Copy link
Owner

gajus commented Jan 6, 2019

Thank you

@gajus
Copy link
Owner

gajus commented Jan 6, 2019

🎉 This issue has been resolved in version 2.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@gajus gajus added the released label Jan 6, 2019
@dcherman
Copy link
Author

dcherman commented Jan 6, 2019

Hey @gajus, thanks for taking a look at this. If you don't mind a suggestion, I'd create a new promise that resolves when your server is closed (or fails to close I guess) rather than calling process.exit() since you can't assume that other resources that the application uses like databases, redis, etc.. have all been cleaned up yet

gajus added a commit that referenced this issue Jan 6, 2019
@gajus
Copy link
Owner

gajus commented Jan 6, 2019

This behaviour is by design.

The idea is that Lightship registers all the shutdownHandler and forces termination after all shutdown handlers have been called.

I have added a warning about the active event loop preventing the program to gracefully exit and changed the exit code to 1.

Does this seem reasonable solution?

If not, please advise how would you handle it, since the requirement is to terminate the program within a given time limit.

@gajus
Copy link
Owner

gajus commented Jan 6, 2019

🎉 This issue has been resolved in version 2.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@dcherman
Copy link
Author

dcherman commented Jan 6, 2019

Ah, yea, that makes a lot of sense. I was thinking about this incorrectly. I think the warning is a nice touch though since that might help people find dangling resources that they missed cleaning up.

In that case, my only remaining suggestion would be to use Promise.all and map to return an array of promises from the shutdown handlers. The current behavior would call each of them in series and possibly cause shutdown to take longer than it otherwise should. Don't think we necessarily need to enforce order here since that can be accomplished in userland if necessary.

@gajus
Copy link
Owner

gajus commented Jan 6, 2019

In that case, my only remaining suggestion would be to use Promise.all and map [..]

Cannot really do that.

Suppose that user does this.

const connection = [..];

registerShutdownHandler(async () => {
  await connection.query([..]);
});

registerShutdownHandler(async () => {
  await connection.end();
});

Using Promise.all would potentially interrupt whatever the dependent shutdown handler is doing.

@dcherman
Copy link
Author

dcherman commented Jan 6, 2019

Sure, but do you feel that it's correct for users to depend on the ordering of shutdown handlers in your lib? It feels more correct for them to have done something like:

  registerShutdownHandler(async () => {
    try {
      await connection.query([..]);
    } finally {
      await connection.end();
    }
});

rather than depending on implementation details of this lib to determine whether or not the resource is still available

@gajus
Copy link
Owner

gajus commented Jan 6, 2019

Fair point.

I will come back to this in a bit.

#6

Don't want to rush the change. Will check how comparable libraries implement shutdown handler execution.

@gajus
Copy link
Owner

gajus commented Nov 5, 2019

This wouldn't be safe though:

registerShutdownHandler(async () => {
    try {
      await connection.query([..]);
    } finally {
      await connection.end();
    }
});

registerShutdownHandler(async () => {
    try {
      await connection.query([..]);
    } finally {
      await connection.end();
    }
});

@gajus
Copy link
Owner

gajus commented Nov 5, 2019

Just do:

registerShutdownHandler(async () => {
  await Promise.all([
    userCollectionOfShutdownHandlers,
  ]);
});

if you need parallelism.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants