| Crates.io | computation-process |
| lib.rs | computation-process |
| version | 0.2.0 |
| created_at | 2025-12-28 22:11:25.233784+00 |
| updated_at | 2025-12-30 12:22:54.091609+00 |
| description | A Rust library for defining stateful computations (and generators) that support suspend/resume, interleaving, cancellation and serialization. |
| homepage | https://github.com/daemontus/computation-process |
| repository | https://github.com/daemontus/computation-process |
| max_upload_size | |
| id | 2009470 |
| size | 87,799 |
computation-process (Suspendable CPU-intensive tasks in Rust)This library provides abstractions for defining "long-running" computations.
The concepts in computation-process are often similar to "normal" asynchronous
code, but offer certain features that were never a priority in asynchronous
programming. The target audience are projects that implement CPU-intensive,
long-running computations but require granular control over the computation state
(e.g., because the computation is controlled from a user interface).
This is currently still very "experimental." I am releasing this on
crates.ioto allow some initial large-scale usage experiments, but please bear in mind that the API can change in the future.
Specific problems for which computation-process offers an opinionated design pattern:
cancel-this crate).
A canceled computation should remain in a consistent state from which it can be
restarted even though some intermediate results may need to be recomputed.Cancellable and Completable: Function returns Cancellable<T> if it can be interrupted
by a cancellation token from cancel-this. A function returns Completable<T>
if it is cancellable, and it also returns Incomplete::Suspended whenever it is safe to
suspend.Computable<T> and Algorithm<CTX, STATE, T>: An object implements Computable<T> if
it can be driven into completion by repeatedly calling try_compute, which returns
Completable<T>. An Algorithm is then an extension of Computable that can be
configured (i.e., created) using CTX and STATE objects, and it provides access to
these objects during computation.Generatable<T> and GenAlgorithm<CTX, STATE, T> are variants of Computable
and Algorithm that do not produce a single value, but rather a "stream" of T values
(like a cancellable/suspendable iterator).Computation and Generator are the default implementations of these interfaces.
They delegate the actual computation to ComputationStep and GeneratorStep while
taking care of the remaining "boilerplate."It is highly recommended to enable LTO when using computation-process because it allows better
inlining of our computation abstractions (at the expense of build time).
To enable LTO, add this to your Cargo.toml:
[profile.release]
lto = true
use computation_process::{Completable, Computable, Computation, ComputationStep, Incomplete, Stateful};
struct CountingStep;
impl ComputationStep<u32, u32, u32> for CountingStep {
fn step(target: &u32, count: &mut u32) -> Completable<u32> {
*count += 1;
if *count >= *target {
Ok(*count)
} else {
Err(Incomplete::Suspended)
}
}
}
fn example() {
let mut computation = Computation::<u32, u32, u32, CountingStep>::from_parts(5, 0);
assert_eq!(computation.compute().unwrap(), 5);
}
use computation_process::{Completable, Generatable, Generator, GeneratorStep, Stateful};
struct RangeStep;
impl GeneratorStep<u32, u32, u32> for RangeStep {
fn step(max: &u32, current: &mut u32) -> Completable<Option<u32>> {
*current += 1;
if *current <= *max {
Ok(Some(*current))
} else {
Ok(None)
}
}
}
fn example() {
let mut generator = Generator::<u32, u32, u32, RangeStep>::from_parts(3, 0);
assert_eq!(generator.try_next(), Some(Ok(1)));
assert_eq!(generator.try_next(), Some(Ok(2)));
assert_eq!(generator.try_next(), Some(Ok(3)));
assert_eq!(generator.try_next(), None);
}