Skip to main content

Tasks

Struct Tasks 

Source
pub struct Tasks { /* private fields */ }
Expand description

One workspace’s durable tasks.

Clone because a handful of this type’s own async fns need an owned copy to move onto a blocking thread (see blocking, below) — every field is already cheap to clone (a path, an Arc), so this costs nothing a caller could not already do by hand.

Implementations§

Source§

impl Tasks

Source

pub fn open(workspace: impl Into<PathBuf>) -> Result<Self, Error>

Opens the durable task store: BASIS_DATA_DIR, else an absolute XDG_DATA_HOME, else the platform data home (created private on first use). workspace is read by spawn and list only; every handle-scoped method resolves straight from the handle, so opening Tasks is cheap and does not itself touch workspace on disk.

Source

pub fn open_at( data_dir: impl Into<PathBuf>, workspace: impl Into<PathBuf>, ) -> Result<Self, Error>

Opens the durable task store at an explicit root, bypassing the BASIS_DATA_DIR/XDG discovery open performs.

For a host that manages its own data directory location rather than the process environment — several Tasks in one process, each with its own root, for one — and for a test that wants no dependency on std::env at all.

Source

pub fn with_prompt_host(self, prompt_host: Arc<dyn PromptHost>) -> Self

Supplies how this Tasks answers Approve::Prompt while it drives a task, and whether it can be asked at all — see PromptHost. Without one, Prompt refuses the same way an unaskable process always did; basis-cli is the first caller of this.

Source

pub fn can_ask(&self) -> bool

Whether this Tasks can currently put an Approve::Prompt question to whoever answers for it — false with no PromptHost supplied.

Source

pub fn store_dir(workspace: &Path) -> Result<PathBuf, Error>

The mentra store directory workspace resolves to, without minting or reading any task.

What a host’s attended, one-shot route — no durable task, no handle — needs to land its conversation store on the same directory spawn would use for the same workspace, so the two share one conversation history and one memory root rather than falling back to two.

Source

pub fn spawn(&self, spec: RunSpec) -> Result<TaskHandle, Error>

Mints a task and returns its handle immediately. Durable and resumable from the moment this returns: nothing has attached yet, and nothing has to for the handle to be good.

Source

pub fn send( &self, handle: &TaskHandle, message: impl Into<String>, ) -> Result<String, Error>

Enqueues a follow-up turn. Never blocks and never drives: the message is durable the moment this returns, and progress happens only once something attaches — ask, wait, or any other attacher.

Source

pub async fn ask( &self, handle: &TaskHandle, caller: Option<&TaskHandle>, message: impl Into<String>, timeout: Duration, ) -> Result<Reply, Error>

Enqueues a follow-up turn and awaits its correlated reply, attaching to drive the task whenever the attach lock is free. send plus wait_message, as one call — the edge is validated before the enqueue, so a rejected wait cannot leave a message behind.

Threading: the edge check and the enqueue are this call’s own synchronous prelude and run through this crate’s own blocking helper; the wait after it is attach::wait_for_message’s own.

Source

pub async fn wait_message( &self, handle: &TaskHandle, caller: Option<&TaskHandle>, message_id: &str, timeout: Duration, ) -> Result<WaitOutcome, Error>

Awaits one already-enqueued message’s correlated reply — the wait --message shape: repeatable without any policy check once the reply exists, and edge-validated only for the wait that has to actually happen.

Threading: the dispatch check and the edge check are this call’s own synchronous prelude and run through this crate’s own blocking helper; the wait after it, when one is still needed, is attach::wait_for_message’s own.

Source

pub async fn wait( &self, handle: &TaskHandle, caller: Option<&TaskHandle>, timeout: Duration, live: Option<Arc<dyn LiveSink>>, ) -> Result<WaitOutcome, Error>

Awaits the task’s terminal record, attaching to drive it whenever the attach lock is free — repeatable: a settled task’s record is read straight off disk, never rerun. live, when given, is shown every event while (and only while) this call is the one driving.

Threading: the terminal read and the edge check are this call’s own synchronous prelude and run through this crate’s own blocking helper; the wait after it, when one is still needed, is this crate’s own wait_unvalidated’s.

Source

pub async fn spawn_and_wait( &self, spec: RunSpec, timeout: Duration, live: Option<Arc<dyn LiveSink>>, ) -> Result<(TaskHandle, WaitOutcome), Error>

Mints a task and immediately attaches to drive it to a terminal result — spawn --await’s shape, and the one place a wait skips edge validation: see this crate’s private wait_unvalidated for why that is safe only here.

Threading: spawn is a synchronous unit in its own right — a directory scan, the continuation lock, create_dir, save_meta — and runs through this crate’s own blocking helper here exactly as it would if this crate wrote it as its own blocking-wrapped prelude; the wait after it is this crate’s own wait_unvalidated’s.

Source

pub fn validate_wait_edge( &self, caller: Option<&TaskHandle>, target: &TaskHandle, ) -> Result<(), Error>

Whether caller (or nobody, for a host outside any task) may wait or ask target — the ownership rule ADR-0017 states: a descendant or an independent root is safe, an ancestor or a peer is not (send it instead, and read the reply from inbox). Err names which rule the edge breaks; a caller that only wants the yes/no can ask for .is_ok().

Source

pub fn validate_cancel_target( &self, caller: Option<&TaskHandle>, target: &TaskHandle, ) -> Result<(), Error>

Whether caller (or nobody, for a host outside any task) may cancel target — downward-only, ADR-0017’s rule: itself or a descendant, never an ancestor or a peer. Err names which rule the target breaks; a caller that wants the refusal to win over an idempotent observation of an already-settled target checks this first, the way basis cancel does.

Source

pub fn cancel( &self, handle: &TaskHandle, caller: Option<&TaskHandle>, ) -> Result<(), Error>

Requests downward cancellation of target and every attached, non-terminal descendant. Idempotent: cancelling an already-settled task is a no-op, and this call never blocks on one settling.

Source

pub fn watch(&self, handle: &TaskHandle) -> Result<EventCursor, Error>

Opens a cursor over the task’s event journal, replay-from-start. Pure observation — this never attaches or drives; poll it in a loop beside terminal for basis watch’s own shape, or just long enough to catch up on a run already in progress.

Source

pub fn terminal(&self, handle: &TaskHandle) -> Result<Option<Value>, Error>

The raw terminal record, or None for a task still resumable. Repeatable and lock-free: existence of terminal.json is the completion signal (ADR-0019).

Source

pub fn is_attached(&self, handle: &TaskHandle) -> Result<bool, Error>

Whether a live executor currently holds the task’s attach lock.

Source

pub fn inbox(&self, handle: &TaskHandle) -> Result<Value, Error>

Every message accepted on the task’s inbox, bounded 4 KiB summaries with truncation metadata — the basis inbox payload shape.

Source

pub fn workspace_of(&self, handle: &TaskHandle) -> Result<PathBuf, Error>

The workspace the task was spawned against, as it was recorded at spawn — not necessarily Tasks::open’s own workspace, since a handle resolves purely from itself.

Source

pub fn list(&self) -> Result<Vec<TaskSummary>, Error>

Every task recorded for this Tasks’s workspace, last worked in first. Empty for a workspace nothing has ever run in — that is a complete answer, not an error.

Trait Implementations§

Source§

impl Clone for Tasks

Source§

fn clone(&self) -> Tasks

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Tasks

§

impl !UnwindSafe for Tasks

§

impl Freeze for Tasks

§

impl Send for Tasks

§

impl Sync for Tasks

§

impl Unpin for Tasks

§

impl UnsafeUnpin for Tasks

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more