← Back to all sparks
P

promises

DEVOPS
Velocity0.0

Asynchronous programming for R using promises and futures

promises drops R6 for plain environments and wires async work into OpenTelemetry

asyncobservabilityperformanceshinypromise-domains
Current state
promises supplies the async primitives behind Shiny and plumber. After years of small domain and future() fixes, the last two releases changed both what a promise costs and what it can report: 1.4.0 corrected nested domain ordering and added the first OpenTelemetry integration, and 1.5.0 replaced the R6 promise class with a classed environment while stabilizing the tracing API.
Where it's heading
Two things are being fixed at once. Promise domains - the mechanism that carries context across async boundaries - have been the source of nearly every bug in this window, and they are now being used deliberately as the vehicle for tracing rather than just for error handling. Meanwhile the object itself is being made cheap enough to create in volume.
Prediction
Expect the OpenTelemetry surface to lose its experimental label and pick up the same span coverage Shiny would need end to end; the deprecated ospan function names should be removed in a following release.

Recent moves

  1. 9mo ago

    OpenTelemetry spans across async work; R6 dropped for environments

    ⚡ SPARK

    Both threads of this trajectory land in one release: tracing context now survives across then() boundaries through a dedicated promise domain, and the promise object stops being an R6 class, cutting creation overhead by up to ten times. The experimental ospan functions from 1.4.0 are already deprecated in favor of the otel names.

    View source ↗
  2. 9mo ago

    Nested promise domains fixed; then() gains a tee argument

    The breaking change is a correctness one - nested domains now wrap callbacks innermost-first, which is what the scoping rules always implied. hybrid_then() lets one code path accept either a promise or a plain value, and then(tee = TRUE) makes side-effect callbacks like logging composable. The first, explicitly experimental, OpenTelemetry integration lands here and is renamed one release later.

    View source ↗
  3. 1y ago

    Realigns future object creation with the future package

    Compatibility work: the way promises constructed future objects was never idiomatic and only worked by accident, so it was rewritten against current future versions. No change to the promises API.

    View source ↗
  4. 1y ago

    Fixes stack overflow on long promise chains

    A same-week regression fix for 1.3.1, where domains active at resolution time stayed active through the handler callback and overflowed the stack on long chains. More evidence that promise domains are where this package's bugs live.

    View source ↗
  5. 1y ago

    Fixes domains forgotten inside nested handlers

    Promise domains were dropped when handlers were registered from within other handlers. Fixed here, and immediately regressed into the stack overflow addressed two days later in 1.3.2.

    View source ↗
  6. 3y ago

    future_promise() returns early when workers are exhausted

    A throughput change for the many-request case: when no future workers are free, future_promise() stops asking and returns for the remainder of the current later cycle, which is faster overall than polling worker availability per request. Also stops spurious unhandled-error reports.

    View source ↗