Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The Standard Library as Architecture

Rust fundamentalsOwnership before synchronizationRevision 89f33cb

Deno’s runtime code is sophisticated, but much of its architecture is visible through ordinary standard-library types.

Future, Poll, Context, and Waker

The entire bridge is built on Rust’s polling contract:

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

Pending means “I cannot finish now, and I arranged for a wake when that may change.” The Deno event loop itself follows this same interface, so Tokio does not need special knowledge of V8.

Rc<T> records isolate-local shared ownership

ResourceTable stores Rc<dyn Resource>, and async ops often receive Rc<RefCell<OpState>>. Rc makes a precise statement: several local owners may retain a value, but it is not being advertised as thread-safe.

A pending read can clone an Rc<TcpStreamResource>. Removing its rid prevents new lookups, while existing operations may still hold the resource. Its close() hook cancels those operations where required.

RefCell<T> gives short, checked mutation windows

An op borrows OpState to retrieve permissions, services, and resources, then drops the borrow before awaiting. RefCell moves enforcement from compile time to runtime, but it does not remove the borrowing rule. Holding a mutable borrow across arbitrary re-entrant JavaScript or .await points would still be a bug.

BTreeMap<ResourceId, Rc<dyn Resource>>

This standard collection is a capability registry. The key is stable enough to cross the JavaScript boundary; the erased value lets files, sockets, subprocess pipes, and cancellation handles coexist. Generic get::<T> restores the expected concrete type or returns BadResourceId.

VecDeque and FuturesUnordered

The op driver uses a completion VecDeque because completed items are locally queued and removed from the front. Pending operations use FuturesUnordered because readiness order, not insertion order, should determine which result is processed next.

These structures solve different problems:

FuturesUnordered: which pending future is ready?
VecDeque:         which already-ready completion is dispatched next?

Option makes lifecycle state explicit

An optional cancellation ID, optional inspector state, optional pending timer, or an enum like the op driver’s MaybeTask makes absence and transitions visible. Production async code frequently consists of making these lifecycle states precise enough that cleanup can cover every path.

The lesson is not “use more locks.” Deno first asks who owns the isolate, who owns a resource, and which values cross a suspension or thread boundary. The chosen standard type follows from those answers.