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)
endOr 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 toChronicle.Client.:connection_string— a connection string binary orChronicle.Connections.ConnectionStringstruct. Defaults toConnectionString.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 totrue.: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_subscriptionsentries.:event_types— list of event type modules to register with the event store.:event_sources— list ofChronicle.EventSources.EventSourcemodules 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 (eachuse Chronicle.Reactors.Reactor).:reducers— list of reducer modules to start (eachuse Chronicle.Reducers.Reducer).:read_models— list of read model modules (eachuse Chronicle.ReadModels.ReadModel). Modules that containfrom/2declarations are registered as model-bound projections.:projections— list of declarative projection modules (eachuse Chronicle.Projections.Projection). These are standalone projection definitions that reference a separate read model module.:constraints— list of standalone constraint modules (eachuse Chronicle.Events.Constraint). These are merged with model-bound constraints declared on registered event types.:global_handlers— list of shared handler modules (eachuse Chronicle.Projections.GlobalHandler). Their mappings are merged into every read model or declarative projection whosevariant_of/2names the same identity; never registered as a projection on their own.:seeders— list of seeder modules (eachuse Chronicle.Seeding.Seeder). Seeders populate the event store with initial events during client startup.:webhooks— list of discoverable webhook modules (eachuse Chronicle.WebHooks.Webhook). These are registered on startup.:captures— list of discoverable capture modules (eachuse Chronicle.Captures.Capture). These are registered on startup (seeChronicle.Captures.register_discovered/1).:event_store_subscriptions— list of discoverable event store subscription modules (eachuse 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. SeeChronicle.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.:ignoreskips the check and its kernel calls.:warnlogs any findings and registers anyway.:faillogs findings and refuses to register when a:warning-severity finding exists (an event type or reactor finding); a reducer or projection finding is:infoand never blocks. If the check itself cannot complete,:warnlogs and continues and:failstops — an indeterminate result is never treated as clean. SeeChronicle.Discovery.DriftDetectorandChronicle.Client.identity_drift/1.:strict_validation— defaults tofalse. 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 totrueto raise at startup instead, before anything connects. SeeChronicle.Events.EventTypes.validate/2.:warn_defaulted_ids— defaults totrue. A reactor, reducer or declarative projection with no explicit:iddefaults 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 tofalseto suppress it. SeeChronicle.Discovery.DefaultedIdWarning.:event_generation_delivery— the default generation delivery (:compatibilityor:pinned) for every reactor and reducer that doesn't set its own:generation_delivery. Defaults to:compatibility. See "Pinned generation delivery" onChronicle.Reactors.ReactorandChronicle.Reducers.Reducer.:skip_tls_validation— overrides the connection string'sskipTlsValidationquery option. SeeChronicle.Connections.Connection.:load_balancer— overrides the connection string'sloadBalancerquery option (:least_connections,:round_robin, or:random), used to pick among multiple hosts or DNS SRV-resolved addresses. SeeChronicle.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 to16. Batches for one partition always run one at a time and in order. Set to1to 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 to5_000, matching the kernel'sconnectedClients.staleThresholdSeconds(5); raise both together.:dedicated_session_channel— defaults totrue. 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 tofalseto share one connection for everything.:concurrency— the default concurrency scope strategy applied to an append that has no explicit:concurrency_scopeand none derived from an event source definition's declared dimensions.default: :none(the default) sends no constraint, matching prior behavior.default: :optimisticreads the tail narrowed the same way the append is routed and expects nothing to have been appended since, mirroring the .NET client'sOptimisticConcurrencyStrategy.check_first_append: false(default) leaves a first append into an empty narrowing unchecked;trueexpects no event matching it yet (seeChronicle.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:
Chronicle.EventSequences.EventLog— append and query eventsChronicle.ReadModels— query read model instancesChronicle.Projections— ad-hoc query a PDL declaration and wait for a projectionChronicle.Events.EventTypes— manage event type registrationsChronicle.Jobs— inspect and control Chronicle jobsChronicle.WebHooks— inspect and register webhooksChronicle.EventStoreSubscriptions— register cross-store subscriptions
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
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()
Returns a specification to start this module under a supervisor.
See Supervisor.
Returns the stored configuration for the given client name.
Used internally by Chronicle.EventSequences.EventLog, Chronicle.ReadModels, etc.
@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.
@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.
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.
@spec start_link(keyword()) :: Supervisor.on_start()
Starts a Chronicle client supervisor linked to the current process.