1 unstable release
Uses old Rust 2015
0.1.0 | Jan 23, 2016 |
---|
#60 in #composable
72 downloads per month
Used in 4 crates
605KB
1K
SLoC
Contains (WOFF font, 120KB) gh-pages/doc/Heuristica-Italic.woff, (WOFF font, 90KB) gh-pages/doc/FiraSans-Medium.woff, (WOFF font, 92KB) gh-pages/doc/FiraSans-Regular.woff, (WOFF font, 56KB) gh-pages/doc/SourceCodePro-Regular.woff, (WOFF font, 56KB) gh-pages/doc/SourceCodePro-Semibold.woff, (WOFF font, 49KB) gh-pages/doc/SourceSerifPro-Bold.woff and 1 more.
rust-cancellation
Rust-Cancellation is a small Rust crate that provides the CancellationToken
type
that can be used to signal cancellation to other code in a composable manner.
Copyright (c) 2016 Daniel Grunwald. MIT license.
Usage
To use cancellation
, add this to your Cargo.toml
:
[dependencies]
cancellation = "0.1"
For more information, see the documentation
lib.rs
:
Rust-Cancellation is a small crate that provides the CancellationToken
type
that can be used to signal cancellation to other code in a composable manner.
Operations that support cancellation usually accept a ct: &CancellationToken
parameter.
They can either cooperatively check ct.is_canceled()
, or use ct.run()
to get notified
via callback when cancellation is requested.
Operations that finish asynchronously may instead accept ct: Arc<CancellationToken>
.
To create a CancellationToken
, use the type CancellationTokenSource
.
A CancellationTokenSource
contains a Arc<CancellationToken>
(which can be obtained using the token()
method, or using deref coercions),
and additionally provides the cancel()
operation to mark the token as canceled.
extern crate cancellation;
use cancellation::{CancellationToken, CancellationTokenSource, OperationCanceled};
use std::{time, thread};
fn cancelable_sum(values: &[i32], ct: &CancellationToken) -> Result<i32, OperationCanceled> {
let mut sum = 0;
for val in values {
try!(ct.result());
sum = sum + val;
thread::sleep(time::Duration::from_secs(1));
}
Ok(sum)
}
fn main() {
let cts = CancellationTokenSource::new();
cts.cancel_after(time::Duration::from_millis(1500));
assert_eq!(Err(OperationCanceled), cancelable_sum(&[1,2,3], &cts));
}
Using the CancellationToken::run()
method, an action can be executed when the token is canceled.
extern crate cancellation;
use cancellation::{CancellationToken, CancellationTokenSource, OperationCanceled};
use std::{time, thread};
use std::time::Duration;
fn cancelable_sleep(dur: Duration, ct: &CancellationToken) -> Result<(), OperationCanceled> {
let th = thread::current();
ct.run(
|| { // the on_cancel closure runs on the canceling thread when the token is canceled
th.unpark();
},
|| { // this code block runs on the current thread and contains the cancelable operation
thread::park_timeout(dur) // (TODO: handle spurious wakeups)
}
);
if ct.is_canceled() {
// The run() call above has a race condition: the on_cancel callback might call unpark()
// after park_timeout gave up after waiting dur, but before the end of the run() call
// deregistered the on_cancel callback.
// We use a park() call with 0s timeout to consume the left-over parking token, if any.
thread::park_timeout(Duration::from_secs(0));
Err(OperationCanceled)
} else {
Ok(())
}
}
fn main() {
let cts = CancellationTokenSource::new();
cts.cancel_after(Duration::from_millis(250));
assert_eq!(Err(OperationCanceled), cancelable_sleep(Duration::from_secs(10), &cts));
}