Skip to main content

Crate taskvisor

Crate taskvisor 

Source
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.

§Choose the runtime entry point

Entry pointUse it when
Supervisor::runA fixed batch finishes naturally
Supervisor::run_untilA fixed batch stops on an application future
Supervisor::run_with_os_signalsTaskvisor should install signal handlers
Supervisor::serveWork 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

ConstructorAfter successAfter a retry-eligible failure
TaskSpec::onceStopStop
TaskSpec::restartableStopRetry if the limit allows
TaskSpec::periodicWait its interval, then repeatRetry 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 reject

A 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 ──► TaskWaiter

The 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

  • tasks defines work, cancellation context, and task specifications.
  • policies defines restart and retry timing.
  • core exposes construction, runtime control, outcomes, and configuration.
  • controller defines optional keyed admission.
  • events and subscribers define best-effort observability.
  • error maps the public error types to their API boundaries.
  • identity explains task IDs, names, and controller slots.
  • prelude re-exports the common application-facing types.

Contributors can follow the source guide for runtime ownership, data flow, and test entry points.

§Feature flags

  • controller enables keyed admission and is enabled by default.
  • logging enables the built-in standard-output subscriber.
  • tracing enables the built-in tracing bridge.
  • tokio-util-interop exposes Tokio’s cancellation token type.
  • test-util exposes 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::SharedError;
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;controller
pub use controller::ControllerConfig;controller
pub use controller::ControllerError;controller
pub use controller::ControllerSnapshot;controller
pub use controller::ControllerSpec;controller
pub use controller::PreparedSubmission;controller
pub use controller::SlotStatusKind;controller
pub use controller::SlotView;controller
pub use subscribers::LogWriter;logging
pub use subscribers::TracingBridge;tracing
pub use subscribers::TracingBridgeWithReasons;tracing

Modules§

controllercontroller
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.