Expand description
§Taskvisor
Taskvisor supervises in-process Tokio tasks that need retries, cancellation, final outcomes, or coordinated shutdown. Its optional controller applies queue, replace, or reject policy per 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 includes the learning path, commands, feature flags, and stop behavior.
- Foundations: basic, task type, graceful worker, application shutdown, periodic, restart policies, and configuration.
- Runtime patterns: outcomes, dynamic tasks, queue consumer, and CPU job.
- Observability: custom subscriber, logging, tracing, and metrics.
- Keyed admission: controller slots, controller admission, and tenant sync.
§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 with add, query, cancel, remove, and shutdown methods.
Supervisor::new accepts runtime configuration and subscribers with default task settings.
Use Supervisor::builder when you need custom TaskDefaults, controller admission,
or typed construction errors through SupervisorBuilder::try_build.
§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 its interval, then repeat | Retry if the limit allows |
Each registration has one TaskId and one internal actor. Attempts for that 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, and 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
SupervisorHandle::add_and_watch returns a TaskWaiter for a direct final TaskOutcome.
A watched result does not depend on the lossy event path, but it is still in-memory and is not
durable across process termination.
Controller users can also choose SupervisorHandle::submit_and_watch.
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 is the key used to coordinate competing submissions.
Different task names can share a slot. Direct add* methods bypass this layer; submit* methods use it.
See AdmissionPolicy for the exact queue, replace, and reject behavior.
§Cancellation and shutdown boundary
Cancellation starts cooperatively. At the configured grace deadline, Taskvisor may report TaskOutcome::ForceAborted
while it keeps owning the unfinished actor until physical exit. While that actor remains active, its synchronous
task code or attempt-future destructor may 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.
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.
Contributors can follow the source guide for 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::ConfigError;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::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 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 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.