defmodule EctoSharding do @moduledoc """ EctoSharding ShardRegistry and Repo supervisor. This is the supervisor that will supervise the internal shard registry and build and supervise the ecto repo for each shard specified in the configuration. Before `start_link` is called all of the shard configuration must be present in the `ecto_sharding` application env. In otherwords, `Application.get_env(:ecto_sharding, Ecto.Sharding)` must return all of the configured shards. This also provides the only public API to the shard registry that consumers should need to interact with, which allows for setting the current shard and retriving the correct repo for the current shard. """ use Supervisor alias EctoSharding.ShardRegistry @typedoc """ The identifier for a shard repo. This will be used to store and lookup each shard repo. It currently only allows integers or strings, but in the future it may support anything that implements `String.Chars` protocol. """ @type shard :: integer | String.t @doc """ Set the current shard to be used for all queries including sharded schemas. """ @spec current_shard(shard) :: :ok def current_shard(shard) do ShardRegistry.current_shard(shard) end @doc """ Get the currently set shard. """ @spec current_shard :: shard def current_shard do ShardRegistry.current_shard end @doc """ Get the queryable repo based on the current shard. """ @spec current_repo :: EctoSharding.Repo.t def current_repo do ShardRegistry.current_repo end @doc """ Start the sharding supervisor. """ @spec start_link :: {:ok, pid} def start_link do Supervisor.start_link(__MODULE__, :ok, []) end @doc false def init(:ok) do shard_repos = EctoSharding.Configuration.shard_repos children = own_children(shard_repos) |> Enum.concat(shard_children(shard_repos)) Supervisor.init(children, strategy: :one_for_one) end defp own_children(shard_repos) do [ {ShardRegistry, [shard_repos: shard_repos]} ] end defp shard_children(shard_repos) do shard_repos |> Enum.map(fn({_shard, module}) -> supervisor(module, []) end) end end