Skip to main content

NATS

This guide discusses operating, configuring, and maintaining NATS as it pertains to supporting Concordance applications.

NATS Core

Concordance relies on underpinnings provided by the NATS server for its stream and persistent data management. Concordance mandates the use of JetStream by any NATS server to which it connects. This is now mandatory for regular wasmCloud applications, so this should already be available "for free" if you're operating wasmCloud lattices.

The following diagram outlines the way in which various NATS elements communicate underneath a Concordance installation.

                                                            .---- AGG_CMD_{entity}
                                    .-----------------.    /
          ---- cc.commands.* -----> |  CC_COMMANDS(S) |---+------ AGG_CMD_{entity}
                                    `-----------------'    \
                                                            `---- AGG_CMD_{entity}

                                                            .---- AGG_EVT_{entity}
                                    .-----------------.    /
          ---- cc.events.* -------> |   CC_EVENTS(S)  |---+------ PM_{entity}
                                    `-----------------'   |
                                                          +------ PROJ_{entity}
                                                          |
                                                          `------ NOTIFIER_{entity}

                                    .-----------------.
        --- aggregate state ---->   |   CC_STATE(K)   |
                                    `-----------------'

S = Stream
K = Key-Value Bucket

Pre-Configuring the Aggregate State Bucket

All aggregate state and project manager state is stored as values in the JetStream key-value bucket CC_STATE. If you do not create this bucket on your own, you will get a default bucket with the following configuration:

Configuration:

          Bucket Name: CC_STATE
         History Kept: 0
        Values Stored: 0
   Backing Store Kind: JetStream
          Description: Concordance state for aggregates and process managers
          Bucket Size: 0 B
  Maximum Bucket Size: unlimited
   Maximum Value Size: unlimited
     JetStream Stream: KV_CC_STATE
              Storage: File

Pre-Configuring Streams and Consumers

The following section describes how all of the various entities are automatically configured by Concordance and which configuration(s) you can override for your own installations.

CC_COMMANDS Stream

CC_COMMANDS is a NATS stream configured as a WorkQueue. If you do not have one created when Concordance is started, you will get one that defaults to the following:

          Description: Concordance command stream for event sourcing capability provider
             Subjects: cc.commands.*
             Replicas: 1
              Storage: File

Options:

            Retention: WorkQueue
     Acknowledgements: true
       Discard Policy: Old
     Duplicate Window: 2m0s
    Allows Msg Delete: true
         Allows Purge: true
       Allows Rollups: false

Limits:

     Maximum Messages: unlimited
  Maximum Per Subject: unlimited
        Maximum Bytes: unlimited
          Maximum Age: unlimited
 Maximum Message Size: unlimited
    Maximum Consumers: unlimited

If you want to use your own custom configuration for the commands stream, then you just need to make sure you create one called CC_COMMANDS that operates on the cc.commands.* topic prior to launching Concordance for the first time. You can change virtually any option you like, however, the stream must remain configured as a WorkQueue with a discard policy of old and it requires acknowledgments. This means that to submit a command into the event sourced system, you'll need to make a request on cc.commands.{type} rather than a publish.

AGG_CMD_{entity} Consumers

Aggregates are the only entities within Concordance that are allowed to read from the command stream. Each command stream consumer in Concordance belongs explicitly to 1 and only 1 aggregate. This means that this aggregate can subscribe explicitly to the stream name on which it rests. Remember that aggregates must not ever share streams.

As with all Concordance streams and consumers, if you provide you own prior to the first launch of Concordance, you can use your own custom configuration. Otherwise, Concordance will use its internal defaults.

The internal default for an aggregate command consumer is as follows:

Configuration:

                Name: AGG_CMD_{entity}
         Description: ... description ...
           Pull Mode: true
      Filter Subject: cc.commands.{entity_name}
      Deliver Policy: All
          Ack Policy: Explicit
            Ack Wait: 3s
       Replay Policy: Instant
  Maximum Deliveries: 3
     Max Ack Pending: 1,000
   Max Waiting Pulls: 512

In the above configuration, you can replace {entity} or {entity_name} with the real entity name. For example, in our bank account example, the aggregate's entity name (and therefore stream name) is bankaccount.

The important thing to take away from this consumer is that it is a pull mode consumer. Work is dispatched from CC_COMMANDS to these consumers where the message is explicitly acknowledged (or nacked). Once acknowledged, the message is removed from the commands stream.

CC_EVENTS Stream

CC_EVENTS is a NATS stream. This stream is configured to default to maintaining an ever-growing history of events. This stream isn't something that should be used for analytics and free-form queries, but is rather designed to be the operational source of events. This stream is not a work queue so acknowledged messages will stay in the stream but advance the consumer pointers. If this stream does not exist, a default one will be created as follows:

          Description: Concordance event stream for event sourcing capability provider
             Subjects: cc.events.*
             Replicas: 1
              Storage: File

Options:

            Retention: Limits
     Acknowledgements: true
       Discard Policy: Old
     Duplicate Window: 2m0s
    Allows Msg Delete: true
         Allows Purge: true
       Allows Rollups: false

Limits:

     Maximum Messages: unlimited
  Maximum Per Subject: unlimited
        Maximum Bytes: unlimited
          Maximum Age: unlimited
 Maximum Message Size: unlimited
    Maximum Consumers: unlimited

AGG_EVT_{entity} Consumers

Aggregates consume both commands and events. They take in commands in order to return a list of events, and they take in events in order to modify their own internal state. As always, Concordance will create a default aggregate event consumer for you if you haven't created one on your own. The default configuration is as follows:

Information for Consumer CC_EVENTS > AGG_EVT_{entity} created 2023-03-28T09:22:08-04:00

Configuration:

                Name: AGG_EVT_{entity}
         Description: ... description ...
           Pull Mode: true
      Deliver Policy: All
          Ack Policy: Explicit
            Ack Wait: 3s
       Replay Policy: Instant
  Maximum Deliveries: 3
     Max Ack Pending: 1,000
   Max Waiting Pulls: 512

When creating your own consumer(s) you don't have to follow Concordance's convention for consumer descriptions. This is just text designed for humans to read.

PM_{entity}

Process managers are event sourced entities that manage and coordinate (some use the word "orchestrate") long-running processes. They do this by ingesting events and emitting commands that will further advance processes. As with all other consumers, they must be explicit-ack pull consumers. The default configuration for PM consumers is:

Information for Consumer CC_EVENTS > PM_{entity} created 2023-03-28T09:22:08-04:00

Configuration:

                Name: PM_{entity}
         Description: ... description ...
           Pull Mode: true
      Deliver Policy: All
          Ack Policy: Explicit
            Ack Wait: 3s
       Replay Policy: Instant
  Maximum Deliveries: 3
     Max Ack Pending: 1,000
   Max Waiting Pulls: 512

PROJ_{entity}

Projectors are "stateless" event handlers (in that Concordance doesn't maintain their state). They take in events and use those to generate read-model data designed for consumer queries. As always Concordance will create a default consumer if one does not already exist. The default configuration for one is as follows:

Information for Consumer CC_EVENTS > PROJ_{entity} created 2023-03-30T08:45:23-04:00

Configuration:

                Name: PROJ_{entity}
         Description: ... description ...
           Pull Mode: true
      Deliver Policy: All
          Ack Policy: Explicit
            Ack Wait: 3s
       Replay Policy: Instant
  Maximum Deliveries: 3
     Max Ack Pending: 1,000
   Max Waiting Pulls: 512