grafos_jobs/lib.rs
1//! grafos-jobs — Idempotent burst compute and retry scaffolding.
2//!
3//! This crate provides a higher-level job runner on top of `grafos-batch`.
4//! It standardizes chunking, idempotent output capture, retries on lease
5//! failure, and teardown semantics — the "pop-up supercomputer" pattern.
6//!
7//! # Core types
8//!
9//! | Type | Purpose |
10//! |------|---------|
11//! | [`WorkChunk`] | Trait for serializable work units with stable IDs |
12//! | [`JobOutputStore`] | Trait for storing/retrieving outputs by chunk ID |
13//! | [`RetryPolicy`] | Configures which errors to retry, max retries, backoff |
14//! | [`JobCoordinator`] | Orchestrates chunk execution with retries and aggregation |
15//!
16//! # Quick start
17//!
18//! ```rust
19//! use grafos_jobs::*;
20//!
21//! // Define a work chunk
22//! #[derive(Clone, serde::Serialize, serde::Deserialize)]
23//! struct Square { value: u64 }
24//!
25//! impl WorkChunk for Square {
26//! fn chunk_id(&self) -> ChunkId { ChunkId(self.value) }
27//! fn to_bytes(&self) -> Vec<u8> {
28//! postcard::to_allocvec(self).unwrap()
29//! }
30//! fn from_bytes(bytes: &[u8]) -> grafos_std::Result<Self> {
31//! postcard::from_bytes(bytes).map_err(|_| grafos_std::FabricError::IoError(-200))
32//! }
33//! }
34//!
35//! // Create a job
36//! let chunks: Vec<Box<dyn WorkChunk>> = vec![
37//! Box::new(Square { value: 2 }),
38//! Box::new(Square { value: 3 }),
39//! ];
40//!
41//! let mut store = MemoryOutputStore::new();
42//! let policy = RetryPolicy::default();
43//!
44//! let mut coord = JobCoordinator::new(policy);
45//! let result = coord.run(
46//! &chunks,
47//! &mut store,
48//! |chunk_bytes| {
49//! let sq: Square = postcard::from_bytes(chunk_bytes)
50//! .map_err(|_| grafos_std::FabricError::IoError(-200))?;
51//! let result = sq.value * sq.value;
52//! Ok(postcard::to_allocvec(&result).unwrap())
53//! },
54//! |outputs| {
55//! let sum: u64 = outputs.iter().map(|(_, v)| {
56//! postcard::from_bytes::<u64>(v).unwrap_or(0)
57//! }).sum();
58//! postcard::to_allocvec(&sum).unwrap()
59//! },
60//! ).unwrap();
61//!
62//! let total: u64 = postcard::from_bytes(&result.aggregate).unwrap();
63//! assert_eq!(total, 4 + 9);
64//! ```
65//!
66//! # Feature flags
67//!
68//! | Feature | Default | Effect |
69//! |---------|---------|--------|
70//! | `std` | Yes | Enables `std` in dependent crates |
71//! | `observe` | No | Enables `grafos-observe` hooks |
72
73#![cfg_attr(not(feature = "std"), no_std)]
74
75extern crate alloc;
76
77mod coordinator;
78mod output_store;
79mod retry;
80mod work_chunk;
81
82pub use coordinator::{JobCoordinator, JobResult};
83pub use output_store::{JobOutputStore, MemoryOutputStore};
84pub use retry::{RetryPolicy, RetryableError};
85pub use work_chunk::{ChunkId, WorkChunk};