Skip to main content

Pending

Struct Pending 

Source
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: InvocationId

Implementations§

Source§

impl<T> Pending<T>

Source

pub fn map_ok<F>(self, f: F) -> Self
where F: FnOnce(T) -> T + Send + 'static,

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

Source

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

Source

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.

Source

pub fn spawn<F>(future: F) -> Self
where F: Future<Output = Result<T, RuntimeError>> + Send + 'static, T: Send + 'static,

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.

Source

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§

Source§

impl<T> Debug for Pending<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Future for Pending<T>

Source§

type Output = Result<T, RuntimeError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

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> 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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T
where T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F> ⓘ
where F: FnOnce(Self::Output) -> U, Self: Sized,

Map this future’s output to a different type, returning a new future of the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U> ⓘ
where Self::Output: Into<U>, Self: Sized,

Map this future’s output to a different type, returning a new future of the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F> ⓘ
where F: FnOnce(Self::Output) -> Fut, Fut: Future, Self: Sized,

Chain on a computation for when a future finished, passing the result of the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B> ⓘ
where B: Future<Output = Self::Output>, Self: Sized,

Wrap this future in an Either future, making it the left-hand variant of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self> ⓘ
where A: Future<Output = Self::Output>, Self: Sized,

Wrap this future in an Either future, making it the right-hand variant of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self> ⓘ
where Self::Output: Future, Self: Sized,

Flatten the execution of this future when the output of this future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where Self::Output: Stream, Self: Sized,

Flatten the execution of this future when the successful result of this future is a stream. Read more
§

fn fuse(self) -> Fuse<Self> ⓘ
where Self: Sized,

Fuse a future such that 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> ⓘ
where F: FnOnce(&Self::Output), Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self> ⓘ
where Self: Sized + UnwindSafe,

Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self> ⓘ
where Self: Sized, Self::Output: Clone,

Create a cloneable handle to this future where all handles will resolve to the same result. Read more
§

fn remote_handle(self) -> (Remote<Self>, RemoteHandle<Self::Output>)
where Self: Sized,

Turn this future into a future that yields () 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>>
where Self: Sized + Send + 'a,

Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where Self: Sized + 'a,

Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self> ⓘ
where Self: Sized,

§

fn never_error(self) -> NeverError<Self> ⓘ
where Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where Self: Sized,

Evaluates and consumes the future, returning the resulting output if the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

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

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

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<F> IntoFuture for F
where F: Future,

Source§

type Output = <F as Future>::Output

The output that the future will produce on completion.
Source§

type IntoFuture = F

Which kind of future are we turning this into?
Source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
Source§

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

Source§

type Error = Infallible

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

impl<F, T, E> TryFuture for F
where F: Future<Output = Result<T, E>> + ?Sized,

§

type Ok = T

The type of successful values yielded by this future
§

type Error = E

The type of failures yielded by this future
§

fn try_poll( self: Pin<&mut F>, cx: &mut Context<'_>, ) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where Self::Ok: Sink<Item, Error = Self::Error>, Self: Sized,

Flattens the execution of this future when the successful result of this future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F> ⓘ
where F: FnOnce(Self::Ok) -> T, Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E> ⓘ
where F: FnOnce(Self::Ok) -> T, E: FnOnce(Self::Error) -> T, Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F> ⓘ
where F: FnOnce(Self::Error) -> E, Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E> ⓘ
where Self: Sized, Self::Error: Into<E>,

Maps this future’s Error to a new error type using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U> ⓘ
where Self: Sized, Self::Ok: Into<U>,

Maps this future’s Ok to a new type using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F> ⓘ
where F: FnOnce(Self::Ok) -> Fut, Fut: TryFuture<Error = Self::Error>, Self: Sized,

Executes another future after this one resolves successfully. The success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F> ⓘ
where F: FnOnce(Self::Error) -> Fut, Fut: TryFuture<Ok = Self::Ok>, Self: Sized,

Executes another future if this one resolves to an error. The error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F> ⓘ
where F: FnOnce(&Self::Ok), Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F> ⓘ
where F: FnOnce(&Self::Error), Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok> ⓘ
where Self::Ok: TryFuture<Error = Self::Error>, Self: Sized,

Flatten the execution of this future when the successful result of this future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where Self::Ok: TryStream<Error = Self::Error>, Self: Sized,

Flatten the execution of this future when the successful result of this future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F> ⓘ
where Self: Sized, F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s Ok type as its Output type. Read more
§

fn into_future(self) -> IntoFuture<Self> ⓘ
where Self: Sized,

Wraps a [TryFuture] into a type that implements Future. Read more
§

fn try_poll_unpin( &mut self, cx: &mut Context<'_>, ) -> Poll<Result<Self::Ok, Self::Error>>
where Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin future types.
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.
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

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