When should you use Tokio's `spawn_blocking`?
Asked Answered
M

1

13

In the task documentation, there's a section that talks about calling blocking code in async, and how that should be avoided as to not block the async thread too much (https://docs.rs/tokio/1.21.2/tokio/task/index.html#blocking-and-yielding).

It also talks about using tokio::task::spawn_blocking for these tasks, but I'm wondering at which point sending the work to a different thread is recommended? I'm currently writing a program that recovers a large amount of ecdsa signatures, which takes about 100 microseconds per message, all while doing a large amount of network IO. As a concrete example, is this enough to use things like spawn_blocking?

Microbiology answered 23/11, 2022 at 13:26 Comment(4)
Does this answer your question? Why does Future::select choose the future with a longer sleep period first?Ridiculous
This might explain better: What is the best approach to encapsulate blocking I/O in future-rs?Ridiculous
I'm not sure that I agree this is a duplicate of those questions - those questions are about how to handle blocking, but this question is more about "what is blocking (and how much is too much)".Strive
Thanks, these are both very helpful posts but not exactly what I was looking for.Microbiology
S
25

Alice Rhyl (one of the Tokio devs) has a good blog post on blocking in async code.

One of the key parts for your question:

To give a sense of scale of how much time is too much, a good rule of thumb is no more than 10 to 100 microseconds between each .await. That said, this depends on the kind of application you are writing.

Given that you're spending 100 microseconds per message, I think you're likely to be getting to the point where moving to a different thread is the right call.

The post also gives a rule of thumb for how to approach moving the work onto different threads:

  • For synchronous IO, use spawn_blocking.
  • For CPU-bound computation, use a separate fork-join thread pool like rayon.
  • For synchronous work that runs forever (e.g. listening to a database connection), spawn your own dedicated thread to avoid taking one away from the Tokio/Rayon pool.
Strive answered 23/11, 2022 at 13:49 Comment(2)
Thank you! I remember reading that article a while back but didn't get a full grasp, will revisit. And in this case, since recovering signatures is CPU bound, isn't something like Rayon the best solution? (I've never used it but have heard about it)Microbiology
@boston: Ah, I thought the network IO you mentioned was the big factor, rather than the signature bit. In that case, Rayon could be worth looking into - that tends to be most effective when the work can be broken down into smaller chunks that can be distributed across CPU cores.Strive

© 2022 - 2024 — McMap. All rights reserved.