Chronicle.Client (cratis_chronicle v3.16.1)

Copy Markdown View Source

Supervisor that manages a Chronicle connection and all registered observers.

Chronicle.Client is the main entry point for the Chronicle Elixir client. Start it in your application's supervision tree, providing a connection string and the list of event types, migrations, reactors, reducers, read models, discoverable webhooks, and discoverable event store subscriptions to register.

Usage

In your Application.start/2:

def start(_type, _args) do
  children = [
    {Chronicle.Client,
      connection_string: "chronicle://localhost:35000",
      event_store: "my-store",
      event_types: [
        MyApp.Events.AccountOpened,
        MyApp.Events.FundsDeposited
      ],
      migrations: [MyApp.Migrations.AccountOpenedV2Migration],
      reactors: [MyApp.Reactors.NotificationReactor],
      reducers: [MyApp.Reducers.AccountReducer],
      read_models: [MyApp.ReadModels.Account],
      webhooks: [MyApp.WebHooks.AccountEvents],
      event_store_subscriptions: [
        MyApp.EventStoreSubscriptions.DefaultAccountEvents
      ]}
  ]

  Supervisor.start_link(children, strategy: :one_for_one)
end

Or enable artifact auto-discovery from an OTP application:

{Chronicle.Client,
  connection_string: "chronicle://localhost:35000",
  event_store: "my-store",
  otp_app: :my_app}

In that mode, Chronicle scans modules in :my_app and discovers artifacts generated by Chronicle macros (use Chronicle.Events.EventType, use Chronicle.Events.Migration, use Chronicle.Seeding.Seeder, use Chronicle.Reactors.Reactor, use Chronicle.Reducers.Reducer, use Chronicle.ReadModels.ReadModel, use Chronicle.WebHooks.Webhook, and use Chronicle.EventStoreSubscriptions.Subscription).

By default, Chronicle also auto-discovers artifacts from loaded modules, so consumers can start with minimal configuration.

Read models that contain from/2, join/2, or removed_with/2 declarations are automatically registered as server-side projections.

Multiple clients

You can start multiple clients with different names:

{Chronicle.Client,
  name: :bank_chronicle,
  connection_string: "chronicle://bank-server:35000",
  event_store: "bank"}

{Chronicle.Client,
  name: :crm_chronicle,
  connection_string: "chronicle://crm-server:35000",
  event_store: "crm"}

Options

  • :name — registered name for this client. Defaults to Chronicle.Client.
  • :connection_string — a connection string binary or Chronicle.Connections.ConnectionString struct. Defaults to ConnectionString.default/0 (localhost:35000).
  • :event_store — the event store name. Defaults to "default".
  • :namespace — the namespace within the event store. Defaults to "default".
  • :discover — enable/disable artifact auto-discovery. Defaults to true.
  • :otp_app — optional OTP application to auto-discover Chronicle artifacts from. When omitted, discovery scans loaded modules. Discovered artifacts are merged with explicit :event_types, :migrations, :reactors, :reducers, :read_models, :webhooks, and :event_store_subscriptions entries.
  • :event_types — list of event type modules to register with the event store.
  • :event_sources — list of Chronicle.EventSources.EventSource modules to register with the event store (also discovered automatically).
  • :migrations — list of migration modules to register with the event store.
  • :reactors — list of reactor modules to start (each use Chronicle.Reactors.Reactor).
  • :reducers — list of reducer modules to start (each use Chronicle.Reducers.Reducer).
  • :read_models — list of read model modules (each use Chronicle.ReadModels.ReadModel). Modules that contain from/2 declarations are registered as model-bound projections.
  • :projections — list of declarative projection modules (each use Chronicle.Projections.Projection). These are standalone projection definitions that reference a separate read model module.
  • :constraints — list of standalone constraint modules (each use Chronicle.Events.Constraint). These are merged with model-bound constraints declared on registered event types.
  • :global_handlers — list of shared handler modules (each use Chronicle.Projections.GlobalHandler). Their mappings are merged into every read model or declarative projection whose variant_of/2 names the same identity; never registered as a projection on their own.
  • :seeders — list of seeder modules (each use Chronicle.Seeding.Seeder). Seeders populate the event store with initial events during client startup.
  • :webhooks — list of discoverable webhook modules (each use Chronicle.WebHooks.Webhook). These are registered on startup.
  • :captures — list of discoverable capture modules (each use Chronicle.Captures.Capture). These are registered on startup (see Chronicle.Captures.register_discovered/1).
  • :event_store_subscriptions — list of discoverable event store subscription modules (each use Chronicle.EventStoreSubscriptions.Subscription). These are registered on startup.
  • :default_sink_type_id — the default sink type used when registering projections and reducers. Accepts an atom (:mongodb, :sql, :in_memory, :none) or a raw sink type string. Defaults to :mongodb. See Chronicle.Sinks.WellKnownSinkTypes.
  • :drift_policy — :ignore, :warn (default) or :fail. Controls what happens when the artifacts about to be registered look like they've drifted from what the kernel already has — an event type generation whose schema changed without a bumped :generation, a registered reactor/reducer/projection missing from the current code, or one whose handled event types changed. :ignore skips the check and its kernel calls. :warn logs any findings and registers anyway. :fail logs findings and refuses to register when a :warning-severity finding exists (an event type or reactor finding); a reducer or projection finding is :info and never blocks. If the check itself cannot complete, :warn logs and continues and :fail stops — an indeterminate result is never treated as clean. See Chronicle.Discovery.DriftDetector and Chronicle.Client.identity_drift/1.
  • :strict_validation — defaults to false. When two modules represent the same generation of an event type, or more than one migrator bridges the same pair of generations, the client logs the full error at startup and continues. Set to true to raise at startup instead, before anything connects. See Chronicle.Events.EventTypes.validate/2.
  • :warn_defaulted_ids — defaults to true. A reactor, reducer or declarative projection with no explicit :id defaults it to the module name — renaming or moving the module then silently resets its observation position. Discovery logs a one-time warning (per module, for the life of the BEAM node) naming the module and how to pin its id; set to false to suppress it. See Chronicle.Discovery.DefaultedIdWarning.
  • :event_generation_delivery — the default generation delivery (:compatibility or :pinned) for every reactor and reducer that doesn't set its own :generation_delivery. Defaults to :compatibility. See "Pinned generation delivery" on Chronicle.Reactors.Reactor and Chronicle.Reducers.Reducer.
  • :skip_tls_validation — overrides the connection string's skipTlsValidation query option. See Chronicle.Connections.Connection.
  • :load_balancer — overrides the connection string's loadBalancer query option (:least_connections, :round_robin, or :random), used to pick among multiple hosts or DNS SRV-resolved addresses. See Chronicle.Connections.LoadBalancer.
  • :max_concurrent_partitions — how many partitions (event sources for a reactor, read model instances for a reducer) each reactor and reducer handles at the same time. Defaults to 16. Batches for one partition always run one at a time and in order. Set to 1 to handle every batch one after another, as versions before 3.16 did.
  • :keepalive_timeout — milliseconds without a keepalive from the kernel after which the session is treated as dead and reconnected. Defaults to 5_000, matching the kernel's connectedClients.staleThresholdSeconds (5); raise both together.
  • :dedicated_session_channel — defaults to true. The session (the Connect stream and its keepalive answers) runs on its own HTTP/2 connection to the same server, so large reactor and reducer results cannot hold its keepalives back. Set to false to share one connection for everything.
  • :concurrency — the default concurrency scope strategy applied to an append that has no explicit :concurrency_scope and none derived from an event source definition's declared dimensions. default: :none (the default) sends no constraint, matching prior behavior. default: :optimistic reads the tail narrowed the same way the append is routed and expects nothing to have been appended since, mirroring the .NET client's OptimisticConcurrencyStrategy. check_first_append: false (default) leaves a first append into an empty narrowing unchecked; true expects no event matching it yet (see Chronicle.Events.ConcurrencyScope.expecting_no_matching_event/1).

Convenience functions

Once started, use Chronicle.append/3 and Chronicle.read_model/3 for the most common operations, or use the subsystem modules directly:

Summary

Functions

Waits until registration has completed, so appends and reads that depend on the registered artifacts can start.

Returns a specification to start this module under a supervisor.

Returns the stored configuration for the given client name.

Returns the artifact discovery report built when this client started.

Returns the most recent artifact identity drift findings computed before registration.

The registration status of a client: whether its event types, constraints, read models, projections and the rest have been registered with the kernel.

Starts a Chronicle client supervisor linked to the current process.

Functions

await_registration(client \\ __MODULE__, timeout \\ 30000)

@spec await_registration(atom(), timeout()) :: :ok | {:error, term()}

Waits until registration has completed, so appends and reads that depend on the registered artifacts can start.

Returns :ok once registered, {:error, {:failed, status}} if the kernel rejected a registration for good (the status carries the kernel's message), or {:error, :timeout}. timeout is in milliseconds (default 30_000).

{:ok, _} = Chronicle.Client.start_link(...)
:ok = Chronicle.Client.await_registration()

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

config(client \\ __MODULE__)

@spec config(atom() | pid()) :: map()

Returns the stored configuration for the given client name.

Used internally by Chronicle.EventSequences.EventLog, Chronicle.ReadModels, etc.

discovery_report(client \\ __MODULE__)

@spec discovery_report(atom()) :: Chronicle.Discovery.Report.t()

Returns the artifact discovery report built when this client started.

See Chronicle.Discovery.Report. Logged at :info (summary) and :debug (full report) during init/1; this is how to get at it afterwards.

identity_drift(client \\ __MODULE__)

@spec identity_drift(atom()) :: [Chronicle.Discovery.Drift.t()]

Returns the most recent artifact identity drift findings computed before registration.

Empty before the first registration attempt, when drift_policy: :ignore, or when none were found. See Chronicle.Discovery.Drift and the :drift_policy client option.

registration_status(client \\ __MODULE__)

@spec registration_status(atom()) :: map()

The registration status of a client: whether its event types, constraints, read models, projections and the rest have been registered with the kernel.

Returns %{state: :pending | :registering | :registered | :failed, attempts: n, error: term | nil, next_retry_in: ms | nil}. Registration is retried with backoff (see Chronicle.Registration.RetryPolicy), so :registering with a non-nil :error means the kernel could not be reached or rejected an attempt, and :failed means it was rejected for good.

start_link(opts \\ [])

@spec start_link(keyword()) :: Supervisor.on_start()

Starts a Chronicle client supervisor linked to the current process.