A complete list of taskmill's capabilities.
- SQLite-backed queue — all tasks are stored in SQLite with WAL journal mode. Tasks survive process restarts, crashes, and power loss.
- Crash recovery — tasks left in
runningstate during a crash are automatically reset topendingon startup. Dedup keys remain occupied so no duplicates sneak in during recovery. - Connection pooling — configurable pool size (default 16) for concurrent reads.
- 256-level priority queue — priorities range from 0 (highest,
REALTIME) to 255 (lowest,IDLE). Five named tiers are provided:REALTIME,HIGH,NORMAL,BACKGROUND,IDLE. Custom values likePriority::new(100)work too. - FIFO within tier — tasks at the same priority are dispatched in insertion order.
- Atomic dispatch — pop operations use
UPDATE ... WHERE id = (SELECT ...) RETURNING *for race-free claiming with no lost tasks. - Runtime-adjustable concurrency — change
max_concurrencyat runtime viaset_max_concurrency().
- Per-group concurrency — assign tasks to named groups via
.group(key)onTaskSubmissionorTypedTask::group_key(). The scheduler limits how many tasks in the same group can run concurrently. - Configurable limits — set per-group limits at build time with
.group_concurrency(group, limit)or a default for all groups with.default_group_concurrency(limit). - Runtime-adjustable — change limits at runtime via
set_group_limit(),remove_group_limit(), andset_default_group_concurrency(). - Independent of global concurrency — group limits are checked in addition to
max_concurrency. A task must pass both the global and group gate to be dispatched.
- Key-based dedup — each task gets a SHA-256 key derived from
task_type + payload(or an explicit key). AUNIQUE(key)constraint withINSERT OR IGNOREprevents duplicate submissions. - Type-scoped keys — the task type is always part of the hash, so different task types never collide even with identical payloads.
- Lifecycle-aware — keys are occupied while a task is pending, running, paused, or retrying. The key is freed when the task moves to history (completed or failed).
- Batch-safe — deduplication applies within
submit_batch()transactions too.
- Expected/actual IO tracking — submit estimated read/write bytes; executors report actual bytes on completion.
- Network IO tracking — tasks can declare expected network RX/TX bytes via
expected_net_io()and report actuals viactx.record_net_rx_bytes()/ctx.record_net_tx_bytes(). - IO budget gating — the scheduler compares running task IO estimates against EWMA-smoothed system throughput. New work is deferred when cumulative IO would exceed 80% of observed disk capacity.
- Learning from history —
avg_throughput()andhistory_stats()compute per-type IO averages from actual completions, enabling callers to refine estimates over time.
- Cross-platform — CPU, disk IO, and network throughput via
sysinfoon Linux, macOS, and Windows. Feature-gated undersysinfo-monitor(enabled by default). - EWMA smoothing — raw samples are smoothed with an exponentially weighted moving average (alpha=0.3, configurable) to avoid spiky readings.
- Two-trait design —
ResourceSampler(raw platform readings) andResourceReader(smoothed snapshots) are separated for testability and custom implementations. - Custom samplers — disable the
sysinfo-monitorfeature and provide your ownResourceSamplerfor containers, cgroups, or mobile platforms. - Network bandwidth pressure — built-in
NetworkPressuresource maps observed RX+TX throughput against a configurable bandwidth cap to backpressure. Enable via.bandwidth_limit(bytes_per_sec)on the builder.
- Composable pressure sources — implement the
PressureSourcetrait to expose a0.0..=1.0signal from any source (API load, memory, battery, queue depth).CompositePressureaggregates sources; the aggregate is the maximum across all. - Throttle policies —
ThrottlePolicymaps(priority, pressure)to dispatch decisions. The default three-tier policy throttlesBACKGROUNDtasks at >50% pressure,NORMALat >75%, and never throttlesHIGHorREALTIME. - Custom policies — define your own thresholds for fine-grained control.
- Priority-based preemption — when a task at or above
preempt_priority(default:REALTIME) is submitted, all lower-priority running tasks are cancelled and paused. - Token-based cancellation — preempted tasks have their
CancellationTokentriggered. Executors should checktoken.is_cancelled()at yield points. - Anti-thrash protection — paused tasks only resume when no active preemptors remain.
- Automatic requeue — retryable failures (
TaskError::retryable(msg)) are requeued at the same priority withretry_count += 1. - Configurable limit —
max_retries(default 3) controls how many times a task can be retried before permanent failure. - Dedup preserved — the key stays occupied during retries, preventing duplicate submission of in-progress work.
- Executor-reported progress — report percentage or fraction-based progress via
ctx.progress().report()orctx.progress().report_fraction(). - Throughput-based extrapolation — for tasks without explicit reports, the scheduler extrapolates progress from historical average duration, capped at 99% to avoid false completion signals.
- Event-driven — progress updates are emitted as
SchedulerEvent::Progressfor real-time UI updates.
- Broadcast channel — subscribe via
scheduler.subscribe()to receiveSchedulerEventvariants:Dispatched,Completed,Failed,Preempted,Cancelled,Progress,Waiting,Paused,Resumed. - Tauri-ready — all events are
Serialize, designed for direct bridging to frontend viaapp_handle.emit().
- Task cancellation — cancel running, pending, or paused tasks via
scheduler.cancel(task_id). - Global pause/resume —
pause_all()stops dispatch and pauses running tasks;resume_all()resumes on the next cycle. Emits events for UI integration. - Task lookup by dedup key —
task_lookup()searches both active and history tables for a task matching a given type and dedup input.
- Builder-style submission —
TaskSubmission::new(type).payload_json(&data)?.expected_io(r, w)for ergonomic construction with serialization. Use.label("display name")to set a human-readable display label independent of the dedup key. - Type-safe deserialization —
ctx.payload::<T>()?in executors for zero-boilerplate extraction. - TypedTask trait — define
TASK_TYPE, default priority, and expected IO on your struct. Submit withscheduler.submit_typed()and deserialize withctx.payload::<T>().
- Hierarchical execution — spawn child tasks from an executor via
ctx.spawn_child(). The parent enters awaitingstate and resumes for finalization after all children complete. - Two-phase execution — implement
TaskExecutor::finalize()for assembly work after children finish (e.g.CompleteMultipartUpload). - Fail-fast — when enabled (default), the first child failure cancels siblings and fails the parent immediately.
- Bulk enqueue —
submit_batch()wraps many inserts in a single SQLite transaction. ReturnsVec<SubmitOutcome>indicating whether each was inserted, upgraded, requeued, or deduplicated.
- Hard mode (default) — immediately cancels all running tasks.
- Graceful mode — stops dispatching, waits for running tasks up to a configurable timeout, then force-cancels stragglers.
- Type-keyed state map — register multiple state types on the builder via
.app_state()/.app_state_arc(). Each type is keyed byTypeId; access from any executor viactx.state::<T>(). - Post-build injection — call
scheduler.register_state(arc)after build to let libraries inject their own state into a shared scheduler. - Arc-based sharing — state is wrapped in
Arcinternally; all tasks share the same instance.
- Automatic retention — configure
RetentionPolicy::MaxCount(n)orRetentionPolicy::MaxAgeDays(n)for automatic history pruning. - Amortized pruning — pruning runs every N completions (default 100, configurable) to avoid per-task overhead.
- Manual pruning —
prune_history_by_count()andprune_history_by_age()for on-demand cleanup.
- Single-call snapshot —
scheduler.snapshot()returns a serializableSchedulerSnapshotwith running tasks, queue depths, progress estimates, pressure readings, and concurrency limits. - Designed for Tauri commands — return the snapshot directly from a
#[tauri::command]handler.
- Builder pattern —
Scheduler::builder()provides fluent construction with sensible defaults. - Clone-friendly —
SchedulerisCloneviaArc<SchedulerInner>for easy sharing in Tauri state and across async tasks. - Serde on all public types — every public struct and enum derives
Serialize/Deserializefor Tauri IPC. - Serializable errors —
StoreErroris serializable for direct use in Tauri command returns.