Skip to content

Instantly share code, notes, and snippets.

@muaazsaleem
Forked from JEG2/pub_sub.exs
Last active April 2, 2016 20:22
Show Gist options
  • Save muaazsaleem/cb86b942bacf2d79a7b11144cf7c1cca to your computer and use it in GitHub Desktop.
Save muaazsaleem/cb86b942bacf2d79a7b11144cf7c1cca 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)
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment