pub struct Pending<T> {
pub id: InvocationId,
/* private fields */
}Expand description
Outcome of an actor-bound mutation. Wraps a oneshot receiver so the caller can await (or block on) the result.
Pending is neither Clone nor Copy – the receiver is
single-use, matching the “one response per request” contract.
Dropping a Pending cancels the wait but does not interrupt the
actor; the response is silently discarded.
Fields§
§id: InvocationIdImplementations§
Source§impl<T> Pending<T>
impl<T> Pending<T>
Sourcepub fn map_ok<F>(self, f: F) -> Self
pub fn map_ok<F>(self, f: F) -> Self
2026-06-02: attach an on-success transform that runs
when the inner result resolves. The transform runs on
the consumer’s polling thread, NOT in a separately
spawned task — critical when the producer is inside a
current_thread runtime that’s about to block in
block_on. Use this instead of Pending::spawn for
purely synchronous result-shape adaptation (e.g.
translating coordinate spaces).
map_ok may be called only once per Pending. A second
call replaces the prior transform (last-write-wins).
Sourcepub fn ready(result: Result<T, RuntimeError>) -> Self
pub fn ready(result: Result<T, RuntimeError>) -> Self
M.1 (2026-05-31): build a Pending<T> that resolves
immediately with result. Used by read-only impls of
crate::Document (MultibufferDocumentHandle) to
reject writes without ever spawning an actor — every
mutating method returns Pending::ready(Err( RuntimeError::ReadOnly)).
Sourcepub fn from_channel(rx: Receiver<Result<T, RuntimeError>>) -> Self
pub fn from_channel(rx: Receiver<Result<T, RuntimeError>>) -> Self
OA.23b: wrap a channel that a task ALREADY RUNNING will complete.
The peer of Self::spawn for producers that have no task
to spawn — the work is already queued somewhere else and all
they hold is the reply end. MultibufferDocumentHandle:: apply_to_source is the case: the edit rides the view’s
source-forwarder FIFO (spawned once, on the shared runtime,
at view construction) and the forwarder answers this channel.
Not a stylistic preference over spawn. spawn calls
tokio::spawn and so needs a runtime in scope at the point
of construction; this path is reached from the editor actor —
a current_thread runtime about to block_on the result —
where spawning the awaiter onto the caller’s own runtime is
the deadlock map_ok was added to avoid.
A dropped sender resolves to ActorGone, as with any other
Pending.
Sourcepub fn spawn<F>(future: F) -> Self
pub fn spawn<F>(future: F) -> Self
M.3 (2026-06-01): build a Pending<T> that resolves when
the spawned future completes. Lets callers compose
multiple Pendings into one without blocking the runtime
(used by MultibufferDocumentHandle::apply_edit_batch to
fan a translated batch across N source handles, await each
source’s Pending asynchronously, and combine the results).
Spawns on the SHARED runtime, never on the ambient one, and that is the whole of its correctness.
It used to call bare tokio::spawn, which lands the task on whatever
runtime happens to be in scope at the point of construction. Every
consumer of a Pending is a document operation, and the host reaches
those from the editor actor — a current_thread runtime that then
blocks itself awaiting the result (block_on(document.save())).
The task is queued on the one thread that is now blocked, so nothing
drives it and the editor wedges permanently, with the operation never
performed.
That is not a hypothetical. It shipped three times: the pre-M.11
apply_edit freeze, the undo freeze, and MultibufferDocument::save
— the user-visible form of the last being “:w on the agenda hangs
forever and the change is not on disk”. The first two were fixed by
making those paths synchronous, which left this constructor still
carrying the trap for the one caller that genuinely needs async work.
Naming the target runtime fixes the class rather than the instance: document actors all live on the shared runtime, so it is where a composition over them belongs. It also drops the old “requires a current tokio runtime context” requirement — there is nothing left to get wrong at a call site.
Self::map_ok and Self::from_channel remain the right tools for
their own cases (a synchronous transform, and a task that is already
running); they are no longer workarounds for this hazard.
Sourcepub fn blocking_recv(self) -> Result<T, RuntimeError>
pub fn blocking_recv(self) -> Result<T, RuntimeError>
Block the current thread until the actor responds. Used by the TUI input loop and by tests that don’t drive a tokio reactor explicitly. Panics only if the oneshot’s internal invariants are violated, which can’t happen in safe code.
Trait Implementations§
Auto Trait Implementations§
impl<T> !RefUnwindSafe for Pending<T>
impl<T> !Sync for Pending<T>
impl<T> !UnwindSafe for Pending<T>
impl<T> Freeze for Pending<T>
impl<T> Send for Pending<T>where
T: Send,
impl<T> Unpin for Pending<T>
impl<T> UnsafeUnpin for Pending<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn map<U, F>(self, f: F) -> Map<Self, F> ⓘ
fn map<U, F>(self, f: F) -> Map<Self, F> ⓘ
§fn map_into<U>(self) -> MapInto<Self, U> ⓘ
fn map_into<U>(self) -> MapInto<Self, U> ⓘ
§fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F> ⓘ
fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F> ⓘ
f. Read more§fn left_future<B>(self) -> Either<Self, B> ⓘ
fn left_future<B>(self) -> Either<Self, B> ⓘ
§fn right_future<A>(self) -> Either<A, Self> ⓘ
fn right_future<A>(self) -> Either<A, Self> ⓘ
§fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
§fn flatten(self) -> Flatten<Self> ⓘ
fn flatten(self) -> Flatten<Self> ⓘ
§fn flatten_stream(self) -> FlattenStream<Self>
fn flatten_stream(self) -> FlattenStream<Self>
§fn fuse(self) -> Fuse<Self> ⓘwhere
Self: Sized,
fn fuse(self) -> Fuse<Self> ⓘwhere
Self: Sized,
poll will never again be called once it has
completed. This method can be used to turn any Future into a
FusedFuture. Read more§fn inspect<F>(self, f: F) -> Inspect<Self, F> ⓘ
fn inspect<F>(self, f: F) -> Inspect<Self, F> ⓘ
§fn catch_unwind(self) -> CatchUnwind<Self> ⓘwhere
Self: Sized + UnwindSafe,
fn catch_unwind(self) -> CatchUnwind<Self> ⓘwhere
Self: Sized + UnwindSafe,
§fn remote_handle(self) -> (Remote<Self>, RemoteHandle<Self::Output>)where
Self: Sized,
fn remote_handle(self) -> (Remote<Self>, RemoteHandle<Self::Output>)where
Self: Sized,
() on completion and sends
its output to another future on a separate task. Read more§fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
§fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>where
Self: Sized + 'a,
fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>where
Self: Sized + 'a,
§fn unit_error(self) -> UnitError<Self> ⓘwhere
Self: Sized,
fn unit_error(self) -> UnitError<Self> ⓘwhere
Self: Sized,
Future<Output = T> into a
TryFuture<Ok = T, Error = ()>.§fn never_error(self) -> NeverError<Self> ⓘwhere
Self: Sized,
fn never_error(self) -> NeverError<Self> ⓘwhere
Self: Sized,
Future<Output = T> into a
TryFuture<Ok = T, Error = Never>.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<F> IntoFuture for Fwhere
F: Future,
impl<F> IntoFuture for Fwhere
F: Future,
Source§type IntoFuture = F
type IntoFuture = F
Source§fn into_future(self) -> <F as IntoFuture>::IntoFuture
fn into_future(self) -> <F as IntoFuture>::IntoFuture
§impl<F, T, E> TryFuture for F
impl<F, T, E> TryFuture for F
§impl<Fut> TryFutureExt for Futwhere
Fut: TryFuture + ?Sized,
impl<Fut> TryFutureExt for Futwhere
Fut: TryFuture + ?Sized,
§fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>where
Self::Ok: Sink<Item, Error = Self::Error>,
Self: Sized,
fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>where
Self::Ok: Sink<Item, Error = Self::Error>,
Self: Sized,
Sink]. Read more