1 stable release
1.0.0 | Dec 31, 2024 |
---|
#355 in Concurrency
119 downloads per month
13KB
198 lines
rayon-cancel
Rayon does not natively provide a way to interrupt long-running computations. When using rayon scopes, it is possible to interrupt the computation by using an atomic flag. This is, however, not easily possible when using rayon's parallel iterators. To this end, this crate provides an iterator adapter, that can be interrupted.
By design, the adapter cannot interrupt processing individual items. Once the computation is cancelled, the adapter will stop producing or consuming new items. Which items are processed before the computation stops is non-deterministic and depends on the way rayon distributes the work.
The provided CancelAdapter
can be used on any rayon iterator and can be used to interrupt processing new items at any given point.
The adapter provides a handle to cancel the computation and a handle to access the number of processed items.
Using this adapter may be less efficient than using the underlying iterator directly as the number of items produced by the iterator cannot be known in advance.
If you only need access to the number of processed items, you may want to have a look at the rayon-progress crate.
Example
use rayon::prelude::*;
use rayon_cancel::CancelAdapter;
let adapter = CancelAdapter::new(0..100000);
let canceller = adapter.canceller();
let progress = adapter.counter();
std::thread::spawn(move || {
while progress.get() < 1000 {
std::thread::sleep(std::time::Duration::from_millis(2));
}
canceller.cancel();
});
let count = adapter.counter();
// some expensive computation
let processed: Vec<_> = adapter.filter(|_| true).map(|i| {
std::thread::sleep(std::time::Duration::from_millis(20));
i
}).collect();
assert!(count.get() > 1000);
assert!(count.get() < 100000);
// `processed` contains `count` items, but which ones is non-deterministic
assert_eq!(processed.len(), count.get());
Dependencies
~1.5MB
~25K SLoC