Current section
Files
Jump to
Current section
Files
lib/pg2pubsub.ex
defmodule Pg2PubSub do
@moduledoc """
Provides methods for subscribing and publishing to named topics.
"""
require Logger
@doc """
Subscribe to a topic
## Parameters
- pid: Process ID for the started PubSub process
- topic: Name of the topic to subscribe to
## Examples
iex> Pg2PubSub.subscribe("foo")
{:ok, :registered}
# subscribing a second time has no effect
iex> Pg2PubSub.subscribe("foo")
{:ok, :registered}
iex> Pg2PubSub.subscribe("foo")
{:ok, :already_registered}
"""
@spec subscribe(String.t) :: term
def subscribe(topic) do
:ok = Logger.debug "#{inspect self} subscribing to #{topic}..."
:pg2.create(topic)
case :pg2.get_members(topic) do
{:error, error} ->
:ok = Logger.error "Publisher failed to get members of topic #{topic}: #{error}"
{:error, error}
pids ->
unless self in pids do
:pg2.join(topic, self)
:ok = Logger.debug "#{inspect self} subscribed to #{topic}"
{:ok, :registered}
else
:ok = Logger.debug "#{inspect self} already subscribed to #{topic}"
{:ok, :already_registered}
end
end
end
@doc """
Unsubscribe from a topic
## Parameters
- pid: Process ID for the started PubSub process
- topic: Name of the topic to unsubscribe from
## Examples
iex> Pg2PubSub.subscribe("foo")
{:ok, :registered}
iex> Pg2PubSub.unsubscribe("foo")
:ok
# unsubscribing when not subscribed will still give an okay result
iex> Pg2PubSub.unsubscribe("foo")
:ok
"""
@spec unsubscribe(String.t) :: term
def unsubscribe(topic) do
:ok = Logger.debug "#{inspect self} unsubscribing from #{topic}..."
case :pg2.leave(topic, self) do
{:error, {:no_such_group, _topic}} ->
:ok = Logger.warn "no subscribers for topic #{topic}"
:ok
:ok ->
:ok = Logger.debug "#{inspect self} unsubscribed from #{topic}"
:ok
end
end
@doc """
Publish to a topic
## Parameters
- pid: Process ID for the started PubSub process
- topic: Name of the topic to unsubscribe from
## Examples
iex> Pg2PubSub.subscribe("foo")
{:ok, :registered}
iex> Pg2PubSub.publish("foo", "bar")
:ok
iex> receive do msg -> msg end
"bar"
"""
@spec publish(String.t, any) :: :ok
def publish(topic, msg) do
case :pg2.get_members(topic) do
{:error, err} ->
{:error, err}
pids ->
for pid <- pids, do: send(pid, msg)
:ok
end
end
end