The Standard Library as Architecture
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.