Skip to content

Instantly share code, notes, and snippets.

@JEG2
Created February 22, 2016 15:49
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JEG2/5517c64ae051092e40e7 to your computer and use it in GitHub Desktop.
Save JEG2/5517c64ae051092e40e7 to your computer and use it in GitHub Desktop.
An example pub/sub server in Elixir.
defmodule PubSubServer do
def start(subscriber_callback \\ nil) do
spawn(__MODULE__, :run, [[ ], subscriber_callback])
end
def subscribe(server, handler) do
send(server, {:subscribe, self})
listen(handler)
end
def publish(server, message) do
send(server, {:publish, message})
end
def run(subscribers, subscriber_callback) do
receive do
{:publish, message} ->
Enum.each(subscribers, &(send(&1, message)))
run(subscribers, subscriber_callback)
{:subscribe, subscriber} ->
if subscriber_callback, do: subscriber_callback.(subscriber_callback)
run([subscriber | subscribers], subscriber_callback)
end
end
def listen(handler) do
receive do
message ->
handler.(message)
listen(handler)
end
end
end
main = self
server = PubSubServer.start(fn subscriber ->
send(main, {:subscriber, subscriber})
end)
listener_count = 10
Stream.repeatedly(fn ->
spawn(fn ->
PubSubServer.subscribe(server, fn message ->
IO.puts "#{inspect self} received: #{message}"
send(main, {:written, message})
end)
end)
end) |> Enum.take(listener_count)
Stream.repeatedly(fn ->
receive do
{:subscriber, _} -> true
end
end) |> Enum.take(listener_count)
PubSubServer.publish(server, "Hello everyone!")
Stream.repeatedly(fn ->
receive do
{:written, _} -> true
end
end) |> Enum.take(listener_count)
@muaazsaleem
Copy link

Hi,
Inside the run function there's " if subscriber_callback, do: subscriber_callback.(subscriber_callback) ", shouldn't this be " if subscriber_callback, do: subscriber_callback.(subscriber)". Also I wonder how it's still working, I am definitely missing sth : )

@nubunto
Copy link

nubunto commented Apr 3, 2016

@muaazsaleem yes, you are right. In the article, the code is different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment