Expand description
§Taskvisor
Taskvisor supervises in-process Tokio tasks that need retries, cancellation, final outcomes, or coordinated shutdown. Its optional controller queues, replaces, or rejects competing work by application key. Supervisor-wide limits still apply.
§Check the fit
Taskvisor is useful when an application needs one or more of these:
- tasks are added, removed, or watched while the service is running;
- task attempts need timeouts, retry limits, or backoff;
- application logic needs the final outcome of one submitted task;
- competing work for the same key must queue, replace older work, or be rejected.
Taskvisor is not a persistent job queue. Runtime state, queued submissions, and task IDs do not survive process exit. Use durable external storage when work must resume after a restart.
§Quick start
A TaskFn turns an async closure into supervised work.
A TaskSpec gives that work a name and selects its lifecycle.
use taskvisor::prelude::*;
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let supervisor = Supervisor::new(SupervisorConfig::default(), vec![]);
let hello = TaskFn::arc(|_ctx| async {
println!("hello from Taskvisor");
Ok(())
});
supervisor
.run(vec![TaskSpec::once("hello", hello)])
.await?;
Ok(())
}Supervisor::run accepts the complete static batch or rejects it.
The method returns after the shared cleanup workflow, not with each task’s outcome.
Use a watched dynamic add when application logic needs that result.
§Continue with a runnable example
The user guide explains the application workflow from task definition through production boundaries. The examples guide lists complete programs, commands, feature flags, and shutdown behavior.
§Choose the runtime entry point
| Entry point | Use it when |
|---|---|
Supervisor::run | A fixed batch finishes naturally |
Supervisor::run_until | A fixed batch stops on an application future |
Supervisor::run_with_os_signals | Taskvisor should install signal handlers |
Supervisor::serve | Work is added and managed at runtime |
run and run_until do not install operating-system signal handlers.
run_with_os_signals is the explicit process-wide opt-in.
Dynamic mode returns a SupervisorHandle for runtime management and shutdown.
Supervisor::new accepts runtime configuration and subscribers with default task settings.
Supervisor::builder supports custom TaskDefaults and controller admission.
SupervisorBuilder::try_build reports typed construction errors.
§Choose task behavior
| Constructor | After success | After a retry-eligible failure |
|---|---|---|
TaskSpec::once | Stop | Stop |
TaskSpec::restartable | Stop | Retry if the limit allows |
TaskSpec::periodic | Wait at least its interval, then repeat | Retry if the limit allows |
Each registration has one TaskId.
Attempts for the same ID never overlap.
RestartPolicy decides whether success repeats and whether a retryable failure may run again.
The retry limit restricts only repeats after failure.
BackoffPolicy and JitterPolicy control failure delays.
A timeout applies to one attempt.
The default retry limit is unlimited.
Set TaskSpec::with_max_retries or a TaskDefaults limit when repeated failure must eventually stop the task.
Task::spawn should return its future promptly.
Put the task’s work inside that future.
Move blocking or CPU-heavy work off Tokio worker threads.
Long-running work must observe TaskContext::cancelled or use TaskContext::run_until_cancelled.
Return TaskError::Canceled after a cooperative stop.
Return TaskError::Fail for a retry-eligible failure or TaskError::Fatal when the actor must stop.
§Get results or observe events
Executing a watched SupervisorHandle::add returns a TaskWaiter for its final TaskOutcome.
A watched result does not depend on the lossy event path.
It remains in-memory and is not durable across process termination.
Controller users can add watch() to the operation returned by SupervisorHandle::submit.
Event and Subscribe are for logs, metrics, tracing, and live diagnostics.
The shared event bus and each subscriber queue are bounded.
Event delivery is best-effort and must not drive application correctness.
§Coordinate work by key
The default controller feature adds keyed admission before registry entry.
Enable the controller for a supervisor with SupervisorBuilder::with_controller, then submit a ControllerSpec.
ControllerSpec ──► controller slot
├── idle ──► registry admission
└── busy ──► queue, replace, or rejectA task name is the registry uniqueness key inside one supervisor.
A controller slot coordinates submissions that must not run together.
Different task names can share a slot.
SupervisorHandle::add bypasses keyed admission.
SupervisorHandle::submit uses it.
See AdmissionPolicy for the exact queue, replace, and reject behavior.
§Cancellation and shutdown boundary
Cancellation starts cooperatively.
After grace expires, TaskOutcome::ForceAborted can arrive before the actor exits physically.
Taskvisor keeps owning that actor until physical exit.
While it remains active, synchronous code or an attempt-future destructor can keep its task name and capacity reservation owned.
Later isolated destruction of terminal task values keeps capacity reserved but does not keep the task name reserved.
Use Supervisor::ownership_snapshot or SupervisorHandle::ownership_snapshot to inspect that separate boundary.
Dropping a non-final public owner leaves the runtime running.
Dropping the final owner can request cancellation but cannot wait for cleanup.
Call SupervisorHandle::shutdown when the cleanup result matters.
§Architecture at a glance
application
├── static batch ──► Supervisor::run*
├── dynamic task ──► SupervisorHandle::add
└── keyed task ──► SupervisorHandle::submit ──► controller
registry ──► TaskActor ──► sequential attempts
runtime components ──► bounded event bus ──► subscriber queues
registry cleanup or watched rejection ──► TaskWaiterThe registry is the source of truth for registered task membership. The controller owns submissions that have not reached the registry. Events only observe the lifecycle. Watched outcomes use a separate one-shot path.
§Crate layout
tasksdefines work, cancellation context, and task specifications.policiesdefines restart and retry timing.coreexposes construction, runtime control, outcomes, and configuration.controllerdefines optional keyed admission.eventsandsubscribersdefine best-effort observability.errormaps the public error types to their API boundaries.identityexplains task IDs, names, and controller slots.preludere-exports the common application-facing types.
The source guide maps runtime ownership, data flow, and test entry points.
§Feature flags
controllerenables keyed admission and is enabled by default.loggingenables the built-in standard-output subscriber.tracingenables the built-intracingbridge.tokio-util-interopexposes Tokio’s cancellation token type.test-utilexposes constructors intended for external tests.
Re-exports§
pub use core::AddOperation;pub use core::CancelOperation;pub use core::ConfigError;pub use core::OwnershipSnapshot;pub use core::RemoveOperation;pub use core::Supervisor;pub use core::SupervisorBuilder;pub use core::SupervisorConfig;pub use core::SupervisorHandle;pub use core::TaskDefaults;pub use core::TaskOutcome;pub use core::TaskOutcomeKind;pub use core::TaskTarget;pub use core::TaskWaiter;pub use tasks::BoxTaskFuture;pub use tasks::Task;pub use tasks::TaskContext;pub use tasks::TaskFn;pub use tasks::TaskRef;pub use tasks::TaskSetting;pub use tasks::TaskSpec;pub use policies::BackoffError;pub use policies::BackoffPolicy;pub use policies::JitterPolicy;pub use policies::RestartPolicy;pub use error::BoxError;pub use error::BuildError;pub use error::Error;pub use error::RuntimeError;pub use error::TaskError;pub use events::BackoffSource;pub use events::Event;pub use events::EventKind;pub use events::RejectionKind;pub use subscribers::Subscribe;pub use subscribers::SubscriberExecution;pub use identity::TaskId;pub use controller::AdmissionPolicy;controllerpub use controller::ControllerConfig;controllerpub use controller::ControllerError;controllerpub use controller::ControllerSnapshot;controllerpub use controller::ControllerSpec;controllerpub use controller::PreparedSubmission;controllerpub use controller::SlotStatusKind;controllerpub use controller::SlotView;controllerpub use controller::Submit;controllerpub use subscribers::LogWriter;loggingpub use subscribers::TracingBridge;tracingpub use subscribers::TracingBridgeWithReasons;tracing
Modules§
- controller
controller - Coordinates tasks that target the same application resource.
- core
- Implements the runtime behind Taskvisor’s public supervision API.
- error
- Explains which error type belongs to each Taskvisor boundary.
- events
- Exposes Taskvisor’s best-effort lifecycle stream for observability.
- identity
- Explains the identities used to submit, manage, and coordinate tasks.
- policies
- Controls whether Taskvisor starts another attempt and when it starts.
- prelude
- Re-exports the types most Taskvisor applications use together.
- subscribers
- Connects best-effort runtime events to application observers.
- tasks
- Defines the work that Taskvisor runs and supervises.