Skip to content

Instantly share code, notes, and snippets.

@anthonylebrun
Last active July 11, 2016 03:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anthonylebrun/f88214ad5a53e312c6b504efc75489ac to your computer and use it in GitHub Desktop.
Save anthonylebrun/f88214ad5a53e312c6b504efc75489ac to your computer and use it in GitHub Desktop.
defmodule PubSub do
@name __MODULE__
use GenServer
# API
def start_link(default \\ %{}) do
GenServer.start_link(__MODULE__, default, name: @name)
end
def subscribe(pid, topic) do
GenServer.call(@name, {:subscribe, pid, topic})
end
def publish(topic, event) do
GenServer.cast(@name, {:publish, topic, event})
end
# Callbacks
def handle_call({:subscribe, pid, topic}, _from, state) do
listeners = Map.get(state, topic, [])
if Enum.member?(listeners, pid) do
{:reply, :noop, state}
else
new_state = Map.update(state, topic, [pid], &([ pid | &1]))
{:reply, :ok, new_state}
end
end
def handle_cast({:publish, topic, event}, state) do
Map.get(state, topic) |> Enum.each(&(send &1, event))
{:noreply, state}
end
end
defmodule LoopListener do
def new do
spawn &loop/0
end
defp loop do
receive do
event -> IO.puts "#{inspect self}: #{event}"
end
loop
end
end
process_1 = LoopListener.new
process_2 = LoopListener.new
PubSub.start_link
PubSub.subscribe(process_1, :general)
PubSub.subscribe(process_2, :general)
PubSub.subscribe(process_2, :software)
PubSub.publish(:general, "Hello everyone!")
PubSub.publish(:software, "Node is Web Scale.")
#=> Hello everyone!
#=> Hello everyone!
#=> Node is Web Scale.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment