-
Notifications
You must be signed in to change notification settings - Fork 115
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
Core::run_until_finished #225
base: master
Are you sure you want to change the base?
Conversation
Thanks for the PR! I'm a little hesitant about adding this though because applications always don't have knowledge of all tasks that they're spawning. For example the tokio-signal library spawns a task that intentionally never exits and it's break this usage pattern. In general though you don't know whether the async libraries you're calling are going to be spawning tasks (like how you don't know whether sync fns spawn threads) so waiting for all tasks to exit may not always be right. Mind elaborating on some of the motivating use cases here? |
It's common to want to support a graceful shutdown by returning control from the core after all work has been finished. For example, you might want to shut down a web server on SIGINT, but only after completing all outstanding requests. To accomplish that in current tokio, you need to contrive a future that will complete only in exactly that circumstance, which requires manually tracking outstanding requests in addition to no longer accepting new ones. Notwithstanding the implementation details of tokio-signal, with the proposed interface no such bookkeeping would be necessary: you would kick off the main connection-accepting task structured to terminate on SIGINT, and then simply
This is a good point which I hadn't thought of when I drafted this PR. However, I believe the proposed high-level semantics are very useful in principle--we just need a way to distinguish tasks that should and should not sustain execution. It seems to me that most cases where code might spawn a task behind-the-scenes that will run forever, rather than returning a The proposed semantics are basically the same as those implemented by libuv. They allow for the design pattern of tokio-signal by allowing you to explicitly tag a task as "unreferenced", which indicates that it should not cause execution to continue. I've found this pattern to be very convenient. I believe something analogous to libuv's approach would make sense here. A mechanism to construct "backround" tasks could be introduced, and |
Thanks for the comment and sorry for the delay, but yeah having a mechanism for "helper tasks" sounds good to me, there's a number of libraries I think I'd use that for. I'm not entirely certain what such an API would look like, but with that I think I'd be ok to add this. |
For me that's the reason for this patch, not against. When gracefully shutting down the server, I want to be sure that all tasks completed, no task left doing unaccounted work. My use case is this: I want use single event loop to start server, start another server, stop first server, start third server and so on. When shutting down the server, I want to keep event loop running, and make sure there's no leak of any resources. To check this property I could write test like this:
(BTW, I think it was an error when |
I don't disagree there's a use case for this. I disagree we should land this as-is. If we added a way to explicitly spawn a "background task" then we would be able to land this. |
Doesn't |
No, |
What's the difference? |
A background task, in the sense used here, is a task that should not sustain the event loop, because it exists only to support the execution of foreground tasks. The distinction is purely a matter of programmer intention, which we need (and do not currently have) an API to express. |
The fundamental issue right now is that a single core can be used by many independent libs and there is no way to signal shutdown. One option might be to have |
I think it's usually pretty clear whether a given task is the core of a process or exists only to support others. The approach previously discussed is IMO a complete (and simpler) solution, I just need to get around to drafting a |
Clear to who? The spawner or the core? I mean, in general there needs to be a way for tasks to have the opportunity to shutdown gracefully... Actor systems use supervision trees + shutdown messages to do this :P that is probably more than we want to do. |
This provides a considerable improvement in ergonomics when you want to stop executing when all work has been completed.
I'm not super familiar with this level of the stack, so please confirm that
Inner::live
is correct before merging.Better ideas for the method name very welcome.