Packages
ex_esdb
0.2.4
0.11.0
0.10.0
0.9.0
0.8.0
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14-alpha
0.0.13-alpha
0.0.12-alpha
0.0.11-alpha
0.0.10-alpha
0.0.9-alpha
0.0.8-alpha
0.0.6-alpha
0.0.5-alpha
0.0.4-alpha
0.0.3-alpha
0.0.2-alfa
0.0.1-alfa
ExESDB is a reincarnation of rabbitmq/khepri, specialized for use as a BEAM-native event store.
Current section
Files
Jump to
Current section
Files
lib/ex_esdb/store_system.ex
defmodule ExESDB.StoreSystem do
@moduledoc """
Supervisor for store-related components.
This supervisor manages the store lifecycle and clustering components.
Uses :rest_for_one strategy to ensure proper startup order.
Startup order (critical for distributed coordination):
1. Store: Core store GenServer - must be fully operational first
2. StoreCluster: Clustering coordination - depends on Store being ready
3. StoreRegistry: Distributed store registry - starts after Store system is stable
This order ensures StoreRegistry only announces a store that is actually ready
to handle requests, preventing race conditions in distributed environments.
"""
use Supervisor
alias ExESDB.Themes, as: Themes
alias ExESDB.StoreNaming
@impl true
def init(opts) do
children = [
# Store must start first as other components depend on it
{ExESDB.Store, opts},
# StoreCluster handles clustering coordination and depends on Store
{ExESDB.StoreCluster, opts},
# StoreRegistry comes last - only starts after Store system is fully operational
{ExESDB.StoreRegistry, opts}
]
IO.puts("#{Themes.system(self(), "StoreSystem is UP")}")
# Use :rest_for_one because each component depends on the previous ones
# StoreCluster depends on Store, StoreRegistry depends on both
Supervisor.init(children,
strategy: :rest_for_one,
max_restarts: 5,
max_seconds: 30
)
end
def start_link(opts) do
store_id = StoreNaming.extract_store_id(opts)
name = StoreNaming.genserver_name(__MODULE__, store_id)
Supervisor.start_link(__MODULE__, opts, name: name)
end
def child_spec(opts) do
store_id = StoreNaming.extract_store_id(opts)
%{
id: StoreNaming.child_spec_id(__MODULE__, store_id),
start: {__MODULE__, :start_link, [opts]},
restart: :permanent,
shutdown: :infinity,
type: :supervisor
}
end
end