Current section
Files
Jump to
Current section
Files
lib/pubsub_manager.ex
defmodule BCUtils.PubSubManager do
@pubsub_config [
adapter: Phoenix.PubSub.PG2,
pool_size: 1
]
@moduledoc """
Manages Phoenix.PubSub startup to avoid conflicts when multiple applications
in the same VM try to start the same PubSub instance.
This module provides utilities to:
- Check if a PubSub instance is already running
- Conditionally start PubSub only if needed
- Provide graceful fallbacks for shared PubSub instances
- Health check existing PubSub instances
## Usage
In your supervision tree:
children = [
BCUtils.PubSubManager.maybe_child_spec(:my_pubsub),
# other children...
]
|> Enum.filter(& &1) # Remove nil entries
## Dependencies
This module requires `phoenix_pubsub` to be available at runtime.
Add it to your `mix.exs`:
{:phoenix_pubsub, "~> 2.1"}
"""
@doc """
Returns a child spec for Phoenix.PubSub if not already started, otherwise nil.
This is the recommended way to use this module in supervision trees.
## Examples
# Will start PubSub if not running
BCUtils.PubSubManager.maybe_child_spec(:my_pubsub)
# Will return nil if already running
BCUtils.PubSubManager.maybe_child_spec(:my_pubsub)
# Usage in supervision tree
children = [
BCUtils.PubSubManager.maybe_child_spec(:ex_esdb_pubsub),
# other children...
]
|> Enum.filter(& &1) # Remove nil entries
## Parameters
- `pubsub_name` - The atom name for the PubSub instance, or nil
- `opts` - Additional options to pass to Phoenix.PubSub (default: [])
## Returns
- `{Phoenix.PubSub, keyword()}` - Child spec if PubSub needs to be started
- `nil` - If PubSub is already running or pubsub_name is nil
"""
@spec maybe_child_spec(atom()) :: {module(), keyword()} | nil
def maybe_child_spec(nil), do: nil
def maybe_child_spec(pubsub_name) when is_atom(pubsub_name) do
if Process.whereis(pubsub_name) do
nil
else
config = Keyword.merge(@pubsub_config, name: pubsub_name)
{Phoenix.PubSub, config}
end
end
end