Edit this page

The history capabilities of the Ditto protocol consists of 3 commands and 4 events that together implement the reactive-streams protocol over any duplex transport layer. For each streaming subscription request, Ditto acts as the reactive-streams publisher of pages of historical events, and the client acts as the subscriber. By reactive-streams means, the client controls how fast pages are delivered to it and may cancel a request before all results are sent.

While connections do not expose or require a duplex transport layer, the streaming subscription protocol is available for them as well: Send commands from client to Ditto via any connection source. For each command, 0 or more events from Ditto to client are published to the reply-target of the source.

For reactive-streams on the JVM, a publisher-subscriber pair is identified by a Subscription object according to reference equality. Similarly, the streaming subscription protocol commands and events of one request are identified by a subscription ID.

Each streaming subscription protocol command or event corresponds to a reactive-streams signal and are bound by the same rules in the reactive-streams specification.

Reactive-streams signal Streaming subscription protocol message topic Type Message direction
Publisher#subscribe <namespace>/<entityName>/<group>/<channel>/streaming/subscribeForPersistedEvents Command Client to Ditto
Subscription#request <namespace>/<entityName>/<group>/<channel>/streaming/request Command Client to Ditto
Subscription#cancel <namespace>/<entityName>/<group>/<channel>/streaming/cancel Command Client to Ditto
Subscriber#onSubscribe <namespace>/<entityName>/<group>/<channel>/streaming/created Event Ditto to Client
Subscriber#onNext <namespace>/<entityName>/<group>/<channel>/streaming/next Event Ditto to Client
Subscriber#onComplete <namespace>/<entityName>/<group>/<channel>/streaming/complete Event Ditto to Client
Subscriber#onError <namespace>/<entityName>/<group>/<channel>/streaming/failed Event Ditto to Client

Interaction pattern

For one request, the commands from client to Ditto should follow this protocol:

subscribe request* cancel?

The client should send one “subscribeForPersistedEvents” command, followed by multiple “request” commands and an optional “cancel” command.

In response to a “subscribeForPersistedEvents” command and after each “request” command, Ditto will send 0 or more events to the client according to the following protocol:

created next* (complete | failed)?

A “created” event bearing the subscription ID is always sent. 0 or more “next” events are sent according to the amount of results requested by the client. A “complete” or “failed” event comes at the end unless the client sends a “cancel” command before the results are exhausted.

There is no special event in response to a “cancel” command. The client may continue to receive buffered “next”, “complete” or “failed” events after sending a “cancel” command.

In addition to the rules of reactive-streams, Ditto guarantees that no “complete” or “failed” event will arrive before the client expresses its readiness by a first “request” command. The reason is to facilitate concurrency at the client side. Without the extra guarantee, a multi-threaded client would have to process a “complete” or “failed” event in parallel of the preceding “created” event. It would put the burden of sequentialization at the client side and complicate the programming there.

Commands from Client to Ditto

Subscribe for persisted events

Sent a “subscribeForPersistedEvents” command to Ditto to start receiving persisted events as results. Ditto will always respond with a “created” event.

Field Value
topic <namespace>/<entityName>/<group>/<channel>/streaming/subscribeForPersistedEvents
path /
value JSON object specifying the options how the persisted events should be selected.
   

The options where to start/stop historical persisted events from can be specified in the value field of a “subscribeForPersistedEvents” command. If no options are provided at all, the complete available history for the specified entity is streamed as a result.

Request

After obtaining a subscription ID from a “created” event, use “request” commands to tell Ditto how many results you are prepared to receive. Ditto will send “next” events until all requested results are fulfilled, the results are exhausted, or an error occurred.

Field Value
topic <namespace>/<entityName>/<group>/<channel>/streaming/request
path /
value JSON object specifying the demand of results.
   

Cancel

After obtaining a subscription ID from a “created” event, use a “cancel” command to stop Ditto from sending more items of the results. Pages in-flight may yet arrive, but the client will eventually stop receiving events of the same subscription ID.

Field Value
topic <namespace>/<entityName>/<group>/<channel>/streaming/cancel
path /
value Identifies a streaming subscription.
   

Events from Ditto to Client

Created

To any “subscribeForPersistedEvents” command, Ditto will always respond with a “created” event.

Field Value
topic <namespace>/<entityName>/<group>/<channel>/streaming/created
path /
value Discloses the ID of a streaming subscription which all subsequent commands should include.
   

Next

Each “next” event contains one item of the results. Ditto will not send more “next” events for a given subscription ID than the total number of items requested by previous “request” commands.

Field Value
topic <namespace>/<entityName>/<group>/<channel>/streaming/next
path /
value JSON object containing one item of the results.
   

Complete

A streaming subscription ends with a “complete” or a “failed” event from Ditto, or with a “cancel” command from the client. Ditto sends a “complete” event when all items of the results are delivered to the client.

Field Value
topic <namespace>/<entityName>/<group>/<channel>/streaming/complete
path /
value Identifies a streaming subscription.
   

Failed

A streaming subscription ends with a “complete” or a “failed” event from Ditto, or with an “cancel” command from the client. Ditto sends a “failed” event when an internal error occurred, or when the client breaches the reactive-streams specification. It is not possible to “request” more items of the streaming subscription results after a “failed” event.

Field Value
topic <namespace>/<entityName>/<group>/<channel>/streaming/failed
path /
value JSON object containing the reason for the failure.