pub struct Scheduler { /* private fields */ }Expand description
IO-aware priority scheduler.
Coordinates task execution by:
- Popping highest-priority pending tasks from the SQLite store
- Checking IO budget against running task estimates and system capacity
- Applying backpressure throttling based on external pressure sources
- Preempting lower-priority tasks when high-priority work arrives
- Managing retries and failure recording
- Emitting lifecycle events for UI integration
Scheduler is Clone — each clone shares the same underlying state.
This makes it easy to hold in tauri::State<Scheduler> or share across
async tasks.
Implementations§
Source§impl Scheduler
impl Scheduler
pub fn new( store: TaskStore, config: SchedulerConfig, registry: Arc<TaskTypeRegistry>, pressure: CompositePressure, policy: ThrottlePolicy, ) -> Self
Sourcepub fn builder() -> SchedulerBuilder
pub fn builder() -> SchedulerBuilder
Create a SchedulerBuilder for ergonomic construction.
Sourcepub fn subscribe(&self) -> Receiver<SchedulerEvent>
pub fn subscribe(&self) -> Receiver<SchedulerEvent>
Subscribe to scheduler lifecycle events.
Returns a broadcast receiver. Events are emitted on task dispatch, completion, failure, preemption, cancellation, and progress. Useful for bridging to a Tauri frontend or updating UI state.
Sourcepub async fn set_resource_reader(&self, reader: Arc<dyn ResourceReader>)
pub async fn set_resource_reader(&self, reader: Arc<dyn ResourceReader>)
Set the resource reader for IO-aware scheduling.
Sourcepub async fn register_state<T: Send + Sync + 'static>(&self, state: Arc<T>)
pub async fn register_state<T: Send + Sync + 'static>(&self, state: Arc<T>)
Register shared application state after the scheduler has been built.
This is useful when library code (e.g. shoebox) needs to inject its
own state into a scheduler that was constructed by a parent
application. Multiple types can coexist — each is keyed by TypeId.
Sourcepub async fn submit(
&self,
sub: &TaskSubmission,
) -> Result<SubmitOutcome, StoreError>
pub async fn submit( &self, sub: &TaskSubmission, ) -> Result<SubmitOutcome, StoreError>
Submit a task.
If the task’s priority meets the preemption threshold, running tasks with lower priority are preempted (their cancellation tokens are cancelled and they are paused in the store).
Sourcepub async fn submit_batch(
&self,
submissions: &[TaskSubmission],
) -> Result<Vec<SubmitOutcome>, StoreError>
pub async fn submit_batch( &self, submissions: &[TaskSubmission], ) -> Result<Vec<SubmitOutcome>, StoreError>
Submit multiple tasks in a single SQLite transaction.
Preemption is triggered once at the end if any inserted or upgraded task has high enough priority.
Sourcepub async fn submit_typed<T: TypedTask>(
&self,
task: &T,
) -> Result<SubmitOutcome, StoreError>
pub async fn submit_typed<T: TypedTask>( &self, task: &T, ) -> Result<SubmitOutcome, StoreError>
Submit a TypedTask, handling serialization automatically.
Uses the priority from TypedTask::priority().
Sourcepub async fn submit_typed_at<T: TypedTask>(
&self,
task: &T,
priority: Priority,
) -> Result<SubmitOutcome, StoreError>
pub async fn submit_typed_at<T: TypedTask>( &self, task: &T, priority: Priority, ) -> Result<SubmitOutcome, StoreError>
Submit a TypedTask with an explicit priority override.
The provided priority replaces whatever TypedTask::priority()
would return, keeping priority out of the serialized payload.
Sourcepub async fn task_lookup(
&self,
task_type: &str,
dedup_input: Option<&[u8]>,
) -> Result<TaskLookup, StoreError>
pub async fn task_lookup( &self, task_type: &str, dedup_input: Option<&[u8]>, ) -> Result<TaskLookup, StoreError>
Look up a task by the same inputs used during submission.
Computes the dedup key from task_type and dedup_input (the
explicit key string or payload bytes — whichever was used when
submitting), then checks the active queue and history in one call.
§Examples
// Using an explicit key (same as TaskSubmission.key = Some("my-file.jpg"))
let result = scheduler.task_lookup("thumbnail", Some(b"my-file.jpg")).await?;
// Using payload-based dedup (same as TaskSubmission.key = None, payload = ...)
let result = scheduler.task_lookup("ingest", Some(&payload_bytes)).await?;Sourcepub async fn lookup_typed<T: TypedTask>(
&self,
task: &T,
) -> Result<TaskLookup, StoreError>
pub async fn lookup_typed<T: TypedTask>( &self, task: &T, ) -> Result<TaskLookup, StoreError>
Look up a TypedTask by value, using its serialized form as the
dedup input.
This mirrors submit_typed — pass the same
struct you would submit and get back its current status.
Sourcepub async fn cancel(&self, task_id: i64) -> Result<bool, StoreError>
pub async fn cancel(&self, task_id: i64) -> Result<bool, StoreError>
Cancel a task by id.
If the task is currently running, its cancellation token is triggered
and it is removed from the active map. If it is pending or paused,
it is deleted from the store. Returns true if the task was found
and cancelled.
Sourcepub async fn try_dispatch(&self) -> Result<bool, StoreError>
pub async fn try_dispatch(&self) -> Result<bool, StoreError>
Try to pop and execute the next task.
Returns true if a task was dispatched, false if no work was available
(empty queue, concurrency limit, IO budget exhausted, or throttled).
Sourcepub async fn run(&self, token: CancellationToken)
pub async fn run(&self, token: CancellationToken)
Run the scheduler loop until the cancellation token is triggered.
This is the main entry point. The loop wakes on three conditions:
- Cancellation — triggers shutdown.
- Notification — a task was submitted or the scheduler was resumed.
- Poll interval — periodic housekeeping (e.g. resuming paused tasks).
On mobile targets (iOS/Android), the notify-based wake avoids the constant 500ms polling that would otherwise prevent the CPU from sleeping.
Sourcepub async fn active_tasks(&self) -> Vec<TaskRecord>
pub async fn active_tasks(&self) -> Vec<TaskRecord>
Snapshot of currently active (in-memory) tasks.
Sourcepub async fn estimated_progress(&self) -> Vec<EstimatedProgress>
pub async fn estimated_progress(&self) -> Vec<EstimatedProgress>
Get estimated progress for all running tasks.
Combines executor-reported progress with throughput-based extrapolation using historical average duration for each task type.
Sourcepub async fn snapshot(&self) -> Result<SchedulerSnapshot, StoreError>
pub async fn snapshot(&self) -> Result<SchedulerSnapshot, StoreError>
Capture a single status snapshot for dashboard UIs.
Gathers running tasks, queue depths, progress estimates, and backpressure in one call — exactly what a Tauri command would return to the frontend.
Sourcepub fn set_max_concurrency(&self, limit: usize)
pub fn set_max_concurrency(&self, limit: usize)
Update max concurrency at runtime (e.g., from adaptive controller or in response to battery/thermal state).
Sourcepub fn max_concurrency(&self) -> usize
pub fn max_concurrency(&self) -> usize
Read current max concurrency setting.
Sourcepub async fn pause_all(&self)
pub async fn pause_all(&self)
Pause the entire scheduler.
Stops the run loop from dispatching new tasks and pauses all
currently running tasks (their cancellation tokens are triggered
and they are moved back to the paused state in the store so
they will be re-dispatched on resume).
Useful when the app is backgrounded, the laptop goes to sleep, or the user clicks “pause all” in the UI.
Sourcepub async fn resume_all(&self)
pub async fn resume_all(&self)
Resume the scheduler after a pause_all.
Clears the pause flag so the run loop will resume dispatching on its next poll tick. Tasks that were paused in the store will be picked up automatically.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Scheduler
impl !RefUnwindSafe for Scheduler
impl Send for Scheduler
impl Sync for Scheduler
impl Unpin for Scheduler
impl UnsafeUnpin for Scheduler
impl !UnwindSafe for Scheduler
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more