Skip to content

Processor

A Processor is an abstract vital definition with several concrete manifestations (see below) that represents any definition capable of processing messages. Processors have handlers to process messages sent to them, and can have inlets and outlets for receiving and sending messages in streams.

RIDDL 2.0 has one unified processor model. Every processor kind is port-bearing, may carry a streaming shape, and may declare a version and a copyright.

Concrete Processor Types

The following definitions are all processors:

  • Adaptor — translates messages between two contexts
  • Context — a bounded context
  • Entity — stateful business object (can have multiple handlers per state)
  • Projector — projects events into queryable data
  • Repository — persistent storage abstraction
  • Streamlet — the generic streamlet, a stream-processing component

Saga and Function are not processors

A Saga and a Function extend the vital definition base rather than Processor, so neither takes a version or a copyright.

A Saga does, however, bear inlets and outlets — being a coordinator, it has messages to receive and emit. A Function does not.

The streamlet Keyword

The generic streaming processor is declared with the streamlet keyword and an optional shape ascription:

streamlet OrderEnricher as flow is {
  inlet RawOrders is event OrderEvent
  outlet EnrichedOrders is event EnrichedOrderEvent

  handler Enrich is {
    on event OrderEvent {
      do "Look up customer details and product information"
      send event EnrichedOrderEvent(OrderEvent.id) to outlet EnrichedOrders
    }
  }
}

The as <shape> ascription is also available on every other processor header — context, entity, adaptor, projector and repository.

processor as a keyword is deprecated

Write streamlet X is { … }. The old spelling still parses and builds the identical node, but draws stream-processor-keyword, and prettify emits streamlet. riddlc will rewrite it for you:

riddlc validate --fix --fix-rule stream-processor-keyword model.riddl

The reasoning is worth knowing, because it explains why this page keeps the word: every processor kind names a thing — entity, repository, projector, adaptor, context — while processor named the abstraction. "Processor" is still exactly the right word for what this page describes, the category all of those belong to. It is only the declaration keyword that moved, to streamlet, which names a thing like its siblings do.

The shape keywords' own deprecation message changed with it, and now reads streamlet X as flow.

Message Delivery

Messages can be delivered to a processor in two ways:

  1. To an inlet — for stream-based message flow, routed by a connector
  2. Directly to the handler — via the tell statement for point-to-point messaging

Ports

An inlet provides the name and data type for an input to the processor. An outlet provides the name and data type for an output. There can be several of each, or none.

Ports may be declared in any processor body, not only in streamlets. An entity may own an outlet through which it publishes its events; a projector may own an inlet.

Shape

A processor's shape describes its streaming arity. It is normally derived from the ports the processor declares, and may optionally be ascribed to state the intent explicitly.

Shape Inlets Outlets Description Synonym
source 0 1+ Originates data and publishes it to outlets
sink 1+ 0 Terminates data flow by consuming from inlets
flow 1 1 Transforms data from one inlet to one outlet cascade
merge 2+ 1 Combines data from several inlets into one outlet fanin
split 1 2+ Routes data from one inlet to several outlets broadcast, fanout
router 1 2+ Routes messages based on content
void 0 0 Declares no ports at all

Fan-in and fan-out are modeled by declaring multiple ports, never by attaching several connectors to one port. See Connector.

Shape validation

  • An ascribed shape that contradicts the declared arity is an Error, naming the ascription, the arity and the derived shape.
  • A processor with at least one port and no ascription draws a suppressible StyleWarning.
  • A portless, unascribed processor draws nothing from this check.

Handlers

A processor contains handlers that specify how the business logic should proceed. For sources, sinks and flows this is straightforward. For splits, merges and routers, the handler specifies how messages received on inlets are transformed and routed to outlets.

Options

The protocol option (one argument) is valid on any processor, and is consumed by AsyncAPI generation.

Occurs In

Contains

flowchart TD
    Processor(["Processor"]) --> PC["Processor contents"]
    PC --> Handler
    PC --> Function
    PC -->|nested| Processor
    PC --> Connector
    PC --> Ports["Inlet · Outlet · Relationship"]
    PC --> Leaves["Type · Constant · Invariant<br/>Version · Copyright · Comment"]