-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Clean shutdown? #180
Comments
It seems that Rocket uses 0.9.x and I double 👍 this issue though. It's critical for production applications. I use the concept (in other languages/frameworks) all the time during a zero-downtime upgrade. |
@mehcode Rocket is on Hyper 0.10, not 0.9. |
Oops. I had the versions wrong. Well.. the rest of the stuff still applies. Non-async Hyper never got closing a server fixed. |
Argh. Would it be possible for Rocket to enter a mode where it just returns a 503 Service Unavailable to any new connections, as it waits for existing requests to finish, so it can do a nearly-graceful shutdown? As long as the currently-open requests finish processing and the managed state is dropped, it's not a huge problem if the server continues accepting new requests and returns errors. |
Good point. However my concern is I need to stop the process. I can just stop sending new requests to a Rocket process and wait maybe N minutes before killing the process. It's a bit hacky but it could work. |
I would really like this as well. Let's get this in at some point. Slating for |
So right now hyper allow keep-alive to be turned off for a connection. hyperium/hyper#1390 |
This needs a new version of hyper: hyperium/hyper#338 (comment) |
Hi! This feature is a show stopper for me, as I am trying to write hardware-in-the-loop testing framework for IoT devices - I'd need to be able to spawn a server for each test case / test fixture and close it on demand. Does this feature require a ton of porting activities or is it just bumping the version and adding some kind of close() method that calls hyper's close? I might like to try to contribute but I am rust newbie... |
@mchodzikiewicz rocket currently uses hyper 0.10, which doesn't support this. Adding it would require changes in both hyper (the unmaintained branch) and Rocket. Upgrading to the latest version of hyper (which does support clean shutdown) is desired for many other reasons, but is also a lot of work and changes Rocket significantly. |
@jebrosen thank you for the clarification. Is there any timeline for this? I do not see any obviously related issues. |
Killing the thread or process that rocket is running on is the most obvious solution that comes to mind (EDIT: cancelling individual threads is very unwise, see discussion further on). Managing a separate process should be cleaner and more portable than a thread, but also more complex to set up. |
Once Rocket finishes the conversion to async, I think this will be pretty simple. Rocket could spawn a future on its thread that will only resolve once a key combination (ctrl+C most likely) is pressed. It could then use the auto-shutdown feature of a runtime to keep the server running until the keybinding is pressed. The downside of this is that we'd have to check for a binary state on every request so we know whether to fulfil it or reject it outright (as we're shutting down). |
Yikes, signal handling! But yes, setting a "please shut down" flag on Ctrl+C should be possible. We should consider exposing some kind of
hyper should be able to do this part for us - https://docs.rs/hyper/0.12.33/hyper/server/struct.Server.html#method.with_graceful_shutdown. But I have not actually tried it yet. |
Just from the documentation, I'd agree it seems Hyper should be able to handle that. It could also avoid the flag check on each request, depending on whether Hyper already sends a 503 in that situation. A This sounds like a useful feature that many would like and wouldn't need a ton of code, so I'll take a look into implementing this, likely early next week. |
An implementation of this (#1079) of this feature will land in the To support a server that can successfully terminate, It works as intended in the main scenarios tested, but there may be some corner cases. I'm going to leave this issue open, though, because there are a few things we should decide before release:
|
I haven't played with the On Ctrl-C HandlingI think rocket's configuration model needs to be iterated on a bit (#852). For now, SIGTERM handling configuration make sense as a rocket::Config option gated behind a cargo feature which is on by default so users can opt out of any dependencies this brings in if they really want to. Injecting ShutdownI don't completely understand how shutdown is done on the I can't think of a case where it makes sense for a library to be able to terminate the application. If the library wants the application to shut down, it should probably be communicated through an abstraction boundary which the user sets up handling for. I don't think this is a common enough case to justify allowing it automatically. |
Yes, As for shutdown injection, I realized this morning that we're only talking about whether libraries should have access to graceful shutdown; libraries have unblockable access to ungraceful shutdown via |
Thanks for pointing out those pitfalls of
|
I can think of one alternative, which would have a simpler API than my #1237 pull request: A response could set a flag; let's call it That way, in-progress files and templates (which probably cover most boring websites) don't get torn, but SSE and WebSocket connections get abruptly cut off, which for extremely long-lived connections like this the client would need to handle anyway. |
i noticed that this is also causing problems when trying to run a rocket server in a containerised environment (kuberentes/openshift): when trying to scale down the pod openshift it will first send a in my understanding with out of interest: it was mentioned here that this should all change once async lands in rocket (and it seems to be planned for 0.5). does anyone already have some insight on whether it will now be possible to implement this with the async version of rocket? for reference here's the kubernetes documentation on pod termination: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods |
This implements the "instant shutdown" flag describe in rwf2#180. rwf2#180 (comment)
This implements the "instant shutdown" flag describe in rwf2#180. rwf2#180 (comment)
This implements the "instant shutdown" flag describe in rwf2#180. rwf2#180 (comment)
This implements the "instant shutdown" flag describe in rwf2#180. rwf2#180 (comment)
This implements the "instant shutdown" flag describe in rwf2#180. rwf2#180 (comment)
This implements the "instant shutdown" flag describe in rwf2#180. rwf2#180 (comment)
This implements the "instant shutdown" flag describe in rwf2#180. rwf2#180 (comment)
This implements the "instant shutdown" flag describe in rwf2#180. rwf2#180 (comment)
I'm excited to report that I've just finished a fully working PoC implementation of graceful shutdown, including a mechanism to allow any part of the application, including infinite responders, to be notified that shutdown is occurring. This will find its way to 0.5 shortly. |
You're the man !!! SO excited for 0.5 |
The crux of the implementation is as follows: * Configurable ctrl-c, signals that trigger a graceful shutdown. * Configurable grace period before forced I/O termination. * Programatic triggering via an application-wide method. * A future (`Shutdown`) that resolves only when shutdown is requested. Resolves #180.
The crux of the implementation is as follows: * Configurable ctrl-c, signals that trigger a graceful shutdown. * Configurable grace period before forced I/O termination. * Programatic triggering via an application-wide method. * A future (`Shutdown`) that resolves only when shutdown is requested. Resolves #180.
The crux of the implementation is as follows: * Configurable ctrl-c, signals that trigger a graceful shutdown. * Configurable grace period before forced I/O termination. * Programatic triggering via an application-wide method. * A future (`Shutdown`) that resolves only when shutdown is requested. Resolves #180.
Is there any way to perform a "clean" shutdown of Rocket, such that any requests currently being handled can finish (and such that managed state can be cleanly dropped)? I'm assuming right now that pressing ^C just kills the program without any graceful shutdown, since I would expect Rocket to print something to stdout otherwise.
Besides not wanting to have a bad experience for users, I'm primarily concerned with the fact that the program I'm writing is using SQLite and therefore killing it abruptly in the middle of any database mutations is probably a bad idea.
The text was updated successfully, but these errors were encountered: