Last active
July 11, 2016 03:47
-
-
Save anthonylebrun/f88214ad5a53e312c6b504efc75489ac to your computer and use it in GitHub Desktop.
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 | |
@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