-
-
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
Graceful shutdown #1079
Graceful shutdown #1079
Conversation
- Use hyper's MakeService implementation with futures API - Use tokio runtime to serve HTTP backend
Minimum rustc bump required for rust-lang/rust#61775
This lets us keep support for keep-alive and remote address while doing other work on async, at the cost of TLS. Abstracting over the connection type will be done more thoroughly later.
This requires some awkward channel and spawning work because Body might contain borrowed data.
Adds body_string_wait and body_bytes_wait functions to LocalRequest for convenience.
This is required to be able to do anything useful with the body in the outgoing response. Request fairings do not appear to need to be async as everything on Data that returns a future moves self and on_request only gets &Data, but the same change in this commit should work for on_request if desired.
Like with response fairings, this is required to be able to do anything useful with the body.
Also update 'static_files' example.
Just a note, it won't be too difficult to add signal handling (ctrl + C), as the |
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.
currently able to be called using the
rocket.shutdown()
method
I think that's currently the biggest flaw with this PR -- nothing can currently call rocket.shutdown()
once the server is started except for Rocket's own request/response plumbing, which definitely shouldn't be calling it. The sender needs to either be threaded through Request
or put in managed state in order to be usable.
As a proof of concept, I think we need a ShutdownHandle
type that implements FromRequest
. That way, someone could write a #[post("/shutdown")]
route or similar. I think we will also need a way to get a ShutdownHandle
for a not-yet-launched rocket instance, which can be sent to another thread.
Just a note, it won't be too difficult to add signal handling
Agreed. Let's look at what it takes to add it once we know it can be made to work in a route or fairing.
Is there anything currently using managed stated within Rocket itself? If not, wouldn't it be best to preserve that expectation? Having a With regard to handling the sender/receiver errors, should the channel be left open after receiving a shutdown signal? I see no reason to, as it would provide a clear indication that the method is being called more than once. |
…ely match the pre-async code.
Let's use this error type for enum Error {
Launch(LaunchError),
Run(Box<dyn std::error::Error>),
} |
Would it be better to use
|
Interesting, I really thought hyper was "erased" from the error type. In that case, I don't mind |
Updated to use an |
For anyone that might be following this PR, I'm going to attempt adding signal handling once tokio-rs/tokio#1498 is figured out. I believe it should just amount to a couple lines added. |
Additionally pin tokio to '=0.2.0-alpha.2'; before this change cargo selects '0.2.0-alpha.3' which hyper does not compile against.
This currently has a small memory leak if the runtime is not coterminous with Rocket.
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.
This does increase our reliance on tokio
; I think we will want to make Ctrl-C handling optional somehow. The overall architecture of this looks fine, but I haven't actually run the code yet myself.
Since the `signal` feature in Tokio is only used when we want the ctrl+c handling, it's not necessary to compile that bit of code if we're not using it.
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.
Some doc nits, and then I think I'm pretty much happy with this once I test it.
Use a newtype wrapper that the client doesn't have access to, ensuring they're not able to access it.
This PR implements a mandatory graceful shutdown on a Rocket instance, which can be called at runtime.
Calling
.get_shutdown_handle()
before launch will return aShutdownHandle
. As shutting things down before starting isn't too useful most of the time, there is alsorocket::shutdown::ShutdownHandle
, which implementsFromRequest
, so it can be used as a request guard. In either situation, calling.shutdown()
will signal the server to shut down.Per a preexisting comment in the code, I've also converted
rocket.launch()
to returnResult<(), LaunchError>
.Resolves #180.