As a C# backend developer, I am very much used to add progress and cancellation parameters to any function which can potentially be long running (regardless of synchronous or asynchronous functions). In C#, there is a canonical way to do this:
void LongRunningFun(int actualParam, IProgress<double> progress, CancellationToken ct) { ... }
async Task LongRunningFunAsync(int actualParam, IProgress<double> progress, CancellationToken ct) { ... }
Is there also a canonical way to introduce progress and cancellation to functions in Rust?
For example, I have seen that (Tokio?) tasks can be cancelled without need for an extra cancellation token parameter. However, is it idiomatic to write asynchronous code just for the sake of getting cancellation for free (even in situations where I am not interested in concurrency)?
Regarding progress, I could think of a Progress trait similar to the IProgress interface in C#. But is there also a standard trait for that purpose, or do I have to write my own one?
I am looking forward to see how actual Rust developers handle progress and cancellation. 😊
There is no standard way to do cancellation or progress currently. I would pass a reference (or Rc
) to Cell
that is set to true when cancellation was requested. You can wrap that in a nice struct (the following is not thread-safe, you can use Arc
and atomics instead):
pub struct CancellationSource {
token: Rc<Cell<bool>>,
}
impl CancellationSource {
pub fn new() -> Self {
Self {
token: Rc::new(Cell::new(false)),
}
}
pub fn request_cancellation(&mut self) {
self.token.set(true);
}
pub fn token(&self) -> CancellationToken {
CancellationToken {
token: Rc::clone(&self.token),
}
}
}
#[derive(Clone)]
pub struct CancellationToken {
token: Rc<Cell<bool>>,
}
impl CancellationToken {
pub fn is_cancellation_requested(&self) -> bool {
self.token.get()
}
}
Dropping/cancelling an async future immediately stops it at the next .await
point. So just making your code async won't help, unless you manually introduce yield points. It is also worth noting that the current cancellation story of futures is considered bad (because it can leads futures into inconsistent state) and the Rust teams are looking for alternative ideas (one possible solution being voluntary cancellation like C#'s).
There may be a crate for cancellation, but I don't know one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With