# `Chronicle.Reactor`
[🔗](https://github.com/Cratis/Chronicle.Elixir/blob/main/lib/chronicle/reactor.ex#L4)

Behaviour and macro for defining Chronicle reactors.

Reactors observe events and react to them with side effects — sending emails,
calling external APIs, updating caches, etc. They run in Chronicle's
observation pipeline and receive events as they are appended.

## Defining a reactor

Use `Chronicle.Reactor` in a module and implement the `handle/2` callback.
Declare which event types the reactor handles using the `@handles` module
attribute.

    defmodule MyApp.Reactors.NotificationReactor do
      use Chronicle.Reactor

      @handles MyApp.Events.AccountOpened
      @handles MyApp.Events.FundsDeposited

      @impl true
      def handle(%MyApp.Events.AccountOpened{} = event, _context) do
        # Send welcome email
        MyApp.Mailer.send_welcome(event.owner_name)
        :ok
      end

      def handle(%MyApp.Events.FundsDeposited{} = event, _context) do
        # Notify account holder
        :ok
      end
    end

## Options for `use Chronicle.Reactor`

  * `:id` — a stable string identifier for this reactor. Defaults to the
    module's full name. Changing this value causes Chronicle to treat this as
    a different reactor and will reset its observation position.

## Registering with Chronicle.Client

    {Chronicle.Client,
      ...
      reactors: [MyApp.Reactors.NotificationReactor]}

## Event context

The second argument to `handle/2` is a map with the following keys:

  * `:event_source_id` — the event source (e.g. aggregate ID)
  * `:sequence_number` — the event's position in the event log
  * `:occurred` — when the event was appended (ISO 8601 string)
  * `:event_store` — the event store name
  * `:namespace` — the namespace
  * `:correlation_id` — the correlation ID for the append operation

## Return values

`handle/2` must return `:ok` on success, or `{:error, reason}` on failure.
Failures are reported back to Chronicle as a failed partition, which can be
retried or replayed.

# `handle`

```elixir
@callback handle(event :: struct(), context :: map()) :: :ok | {:error, term()}
```

Handles an event dispatched by Chronicle.

Called once per event for each partition. Must return `:ok` or `{:error, reason}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
