VI Platform Services

Extensions

The execution model — components, operations, state, events — is the core of the runtime. It is deliberately small. Most of what a real application also needs is not part of it: an HTTP gateway, configuration, logs, a cache, scheduled work.

These capabilities are provided by extensions. An extension adds to the platform without changing the model, and an application uses it by declaration. The gateway is an extension. So are cadence and continuity.

§What an extension contributes

An extension can contribute in several ways, and most use more than one.

An aspect. A capability added to the operation context: context.stash, context.storages, context.logs. This is how business logic uses an extension.

A service. A process of its own that runs beside the application’s components. The gateway is a service: it listens for HTTP and calls operations.

Components. An extension can bring ordinary Toa components. Those that store credentials and roles come with the gateway, and they have state, operations, and events like any other.

Behavior around components. An extension can act on what components do without being called by them: routing their events to realtime streams, recording the calls between them, calling their operations on a schedule.

§Two places to declare

An application addresses an extension from two places, matching the two concerns separated in The Big Picture.

A component manifest states what the component needs from the extension. This is a logical concern, and it travels with the component:

# orders/manifest.toa.yaml
stash: ~

exposition:
  /:id:
    GET: observe

cadence:
  expire: 3600

The Context states how the extension is set up for the application as a whole. These declarations are called annotations. They are a deployment concern, and they vary by environment:

# context.toa.yaml
stash: redis://cache.example.com

exposition:
  authorities:
    main: api.example.com

The manifest says the component uses a cache; the Context says where the cache is. Neither knows the other’s half.

§Supplied extensions

ExtensionProvides
ExpositionThe gateway: resources, identity and access, realtime, procedures and tools.
ConfigurationValidated configuration values and secrets.
TelemetryLogs, traces, and metrics.
IntrospectionThe topology of the running application.
CadencePulses and delayed calls.
ContinuityEffects that resume where they failed.
ConvergenceRegions of one application converging on the same state.
StoragesStorage for binary objects.
StashA cache shared by a component’s replicas.
StateMemory belonging to one process of a component.
FetchHTTP requests to systems outside the application.

Some are present for every component without being asked for. Others take effect when a component or the Context declares them, and cost nothing otherwise.

§The same mechanism for everyone

Extensions are not a privileged part of the runtime. They are packages that use a public interface, and an application can write its own for capabilities the supplied ones do not cover: an aspect wrapping an internal system, or a service that runs beside the components.

This keeps the trade of product–platform separation open at its edge. When an application meets a platform concern the runtime does not address, the answer is to implement it once as an extension, where every component can declare its use. Building it into the business logic of each component is what the model exists to avoid.

§Extensions and guarantees

An extension works within the model and is subject to its rules.

Interactions through an aspect are visible to the runtime, which is what allows a call made through one to be traced or, in a continuous effect, given back. A service that calls operations is a caller like any other, and its calls are part of chains. Components brought by an extension commit, publish, and converge exactly as the application’s own.

An application built from the core and its extensions therefore behaves as one system, with one set of guarantees.

Search
Search the documentation