VII Running

Compositions

A composition is the physical boundary of an application: a group of components running as one process. It is also the unit an operator works with.

§The unit of deployment and scale

A composition is what gets built, deployed, and replicated.

# context.toa.yaml
compositions:
  - name: core
    components: [orders, billing, inventory]
    replicas: 3
  - name: reports
    components: [reports]
    replicas: 1

Every replica of a composition runs all of its components. Scaling core to three replicas gives three processes, each serving orders, billing, and inventory. Components in one composition scale together, restart together, and share the resources the composition is given.

A component that no composition lists is given a composition of its own. Leaving compositions out entirely therefore yields one process per component, and listing every component in one composition yields a single process. Both are valid starting points.

§What grouping decides

Grouping is an operational decision, and several independent considerations bear on it.

Calls between members stay in memory. Components that call each other often are cheaper together.

Members share connections. A process opens one connection to each piece of infrastructure it uses — a broker, a database, a cache — however many of its components use it. Ten components in one composition hold what one of them would; in ten compositions they hold ten times as much. What an application costs its infrastructure in connections follows from its compositions and their replicas, not from the number of its components.

Members share fate. A defect that exhausts memory in one component takes down the process and everything in it. Isolation is bought with separate compositions.

Members share a scale. A component with a very different load from its neighbors forces them to be replicated with it, or it with them.

Members share a release. A composition is rebuilt and redeployed when any of its members changes.

Members share a queue of attention. Work that takes minutes, such as long tasks, competes with the short work of its neighbors.

None of these appears in component code, so the decision can be changed as evidence accumulates. The topology shows which components actually talk to each other, which is the best input for it.

§Replicas

Replicas of a composition are interchangeable. They take calls from the same queues and events from the same subscriptions, and each call or event is handled by one of them.

Two facts about replicas matter to how an application behaves.

More than one is the normal case. The runtime’s guarantees are designed for it, and running a single replica removes the redundancy they assume. Deployments default to more than one.

Replicas of different versions coexist. During a rollout, old and new replicas serve together for a time. Contracts describes what that requires.

§Resources

A composition states what it may consume in processor time and memory, or inherits a default from the Context. For each of the two it states a request and a limit:

compositions:
  - name: core
    components: [orders, billing, inventory]
    resources:
      cpu: [500m, 2]
      memory: [512Mi, 2Gi]

The request is what a replica is promised: it is placed only where that much is free. The limit is what it may not exceed: processor time beyond it is withheld, and a replica that takes more memory is stopped and started again.

Both are stated for the process, and its members are not divided within it. A component that takes the memory takes it from its neighbors, which is the shared fate that grouping accepts.

These numbers are part of the declaration for the same reason compositions are: they are properties of how the application runs, they vary by environment, and they belong with the other deployment decisions.

§Services in a composition

The services that extensions provide — the gateway and others — are processes too. By default each is deployed on its own. A composition can instead include a service, which then runs inside the composition’s process:

compositions:
  - name: edge
    components: [orders]
    services: [exposition]

This is the same trade as grouping components. Fewer processes cost less to run and are simpler to operate; separate ones are isolated and scale independently. At one end of the range is the single-process form, where every component and every service runs together.

§Leaving things out

An application is sometimes larger than what one deployment should run. A component may be operated by another team on other infrastructure, or run on special hardware outside the cluster.

Such a component can be evicted from a deployment. It remains part of the application: other components call it by name, receive its events, and are held to its contract. The deployment does not start it, and something else is expected to.

Eviction keeps the logical architecture whole where the physical architecture is not uniform. The application is still described once, and the description says which parts this deployment takes responsibility for.

Search
Search the documentation