Last active
July 19, 2023 16:48
-
-
Save alexdesousa/4d592fe206cca17393affaefa4c8fd33 to your computer and use it in GitHub Desktop.
Small pubsub implementation using pg2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule PubSub do | |
@moduledoc """ | |
This module defines the basic pub-sub functions. | |
""" | |
@typedoc """ | |
Channel name. | |
""" | |
@type channel :: term() | |
@typedoc """ | |
Message. | |
""" | |
@type message :: term() | |
@doc """ | |
Subscribes to a `channel`. | |
""" | |
@spec subscribe(channel()) :: :ok | {:error, {:no_such_group, channel()}} | |
def subscribe(channel) do | |
pid = self() | |
case :pg2.get_members(channel) do | |
members when is_list(members) -> | |
if pid in members, do: :ok, else: :pg2.join(channel, pid) | |
{:error, {:no_such_group, ^channel}} -> | |
:pg2.create(channel) | |
:pg2.join(channel, pid) | |
end | |
end | |
@doc """ | |
Unsubscribe from a `channel`. | |
""" | |
@spec unsubscribe(channel()) :: :ok | |
def unsubscribe(channel) do | |
pid = self() | |
case :pg2.get_members(channel) do | |
[^pid] -> | |
:pg2.leave(channel, pid) | |
:pg2.delete(channel) | |
members when is_list(members) -> | |
if pid in members, do: :pg2.leave(channel, pid), else: :ok | |
_ -> | |
:ok | |
end | |
end | |
@doc """ | |
Publishes a `message` in a `channel`. | |
""" | |
@spec publish(channel(), message()) :: :ok | |
def publish(channel, message) do | |
case :pg2.get_members(channel) do | |
[_ | _] = members -> | |
for member <- members, do: send(member, message) | |
:ok | |
_ -> | |
:ok | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment