commanded / eventstore

Event store using PostgreSQL for persistence
MIT License
1.06k stars 146 forks source link

Support multiple event stores #168

Closed slashdotdash closed 5 years ago

slashdotdash commented 5 years ago

This pull request adds support for defining and running multiple event store modules within a single Elixir application.

Getting started

First, you must define your own event store module using the EventStore macro:

defmodule MyApp.EventStore do
  use EventStore, otp_app: :my_app

  # Optional `init/1` function to modify config at runtime.
  def init(config) do
    {:ok, config}
  end
end

You can name your event store module however you like.

Secondly, configure the MyApp.EventStore module in config/config.exs:

config :my_app, MyApp.EventStore,
  serializer: EventStore.JsonSerializer,
  username: "postgres",
  password: "postgres",
  database: "myapp_eventstore",
  hostname: "localhost",
  pool_size: 10

Finally, the event store module must be included within your application's supervision tree (e.g. in lib/my_app/application.ex, inside the start/2 function):

defmodule MyApp.Application do
  use Application

  def start(_type, _args) do
    children = [
      MyApp.EventStore
    ]

    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Optionally, you can configure the event store modules in config/config.exs to allow running the event store mix tasks without providing the event store module as a command line argument:

config :my_app, event_stores: [MyApp.EventStore]

The above configuration allows you to run mix event_store.init instead of mix event_store.init -e MyApp.EventStore (as an example).

Usage

Use your event store module exactly as you would have previously used the EventStore itself.

:ok = MyApp.EventStore.append_to_stream(stream_uuid, expected_version, events)

For ease of upgrading you can alias your own event store module:

alias MyApp.EventStore, as: EventStore

:ok = EventStore.append_to_stream(stream_uuid, expected_version, events)

You can define and use as many different event store modules as you like. Each store will use its own separate database and be completely isolated from one another.