-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Add spawn_pinned to tokio-util #3370
Conversation
The pinned workers don't shut down when the tokio runtime does, so the included test never completes. The worker count is currently hard-coded with a fixme. PinnedPool does not reset, so if a second runtime is started after the first finishes, spawn_pinned will not work (the first issue about not shutting down the workers prevents this scenario from happening atm).
It seems like this is a lot of complexity that could be avoided if your database client was Sync. That might be a more reasonable route? |
I would like to avoid that. The specific DB in my use case is SQLite, but there are other This is a hard to work around limitation of the multithreaded executor, so I think it's important to provide a general solution instead of only fixing my specific case. |
Global pool approach is something new for Tokio and Tokio-util. I'd consider instead: fn new_local_pool(/*some config, e.g. thread count*/) -> Handle;
struct Handle: Clone;
impl Handle {
fn spawn(&self, fut) -> JoinHandle;
} This way user can configure local pool (and use multiple pools if they wish). |
Thanks for the insight and suggestion @MikailBag! I'll rework the code to implement that. |
@MikailBag Is there anything blocking review of this PR? |
IMHO your PR looks good. Please note that I'm not Tokio maintainer though. |
I haven't had time to look closely at this PR yet, sorry. |
I'll try and make time to go through this later. |
@Darksonn I patched up the issues related to task cancellation and task count decrementing. I think it's much more robust now. |
c4fa5c9
to
c130046
Compare
Co-authored-by: Alice Ryhl <aliceryhl@google.com>
@Darksonn I think this PR is pretty close to being merged. Could you take another look? |
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.
Thanks, it seems good.
Sorry about the many delays in reviewing this. |
Thanks for reviewing! |
Motivation
Sometimes when running a task the program has to handle
!Sync
data. For example, this could be a database connection (Send + !Sync
) which will be passed to other async functions by reference when processing a web server request. Because the connection is!Sync
and it is captured as an argument to an async function, the resulting future is!Send
. Currently the only way tokio can execute!Send
futures is by starting aLocalSet
and usingspawn_local
. This does not work very well when the multi-threaded runtime is used. More context is in #2545.Solution
This PR introduces
tokio_util::task::LocalPoolHandle
based on the discussion in #2545 and this PR:The idea for
spawn_pinned
is to take in anFnOnce
which will create the!Send
future. The closure will be sent to a thread which runs aLocalSet
on the single-threaded executor. The thread is chosen from a small group of worker threads based on load.