Skip to content

Instantly share code, notes, and snippets.

@filipevarjao
Created August 10, 2021 00:35
Show Gist options
  • Save filipevarjao/09fae7effa28cb6928fa3f5e8f234224 to your computer and use it in GitHub Desktop.
Save filipevarjao/09fae7effa28cb6928fa3f5e8f234224 to your computer and use it in GitHub Desktop.
# Zap
defmodule Zap do
use GenServer
@type state :: map()
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def nodes_online() do
GenServer.call(__MODULE__, :online)
end
def send_msg(node_name, msg) do
GenServer.cast(__MODULE__, {:send_msg, node_name, msg})
end
def init(_) do
nodes = Node.list()
Process.send_after(self(), :refresh, 10_000)
{:ok, transform_node_name(nodes)}
end
def handle_call(:online, _from, state) do
{:reply, Map.keys(state), state}
end
def handle_cast({:send_msg, node_name, msg}, state) do
maybe_send_msg(node_name, msg, state)
{:noreply, state}
end
def handle_info(:online, state) do
IO.puts Map.keys(state)
{:noreply, state}
end
def handle_info(:refresh, state) do
nodes = Node.list()
Process.send_after(self(), :refresh, 10_000)
{:noreply, transform_node_name(nodes)}
end
def handle_info({:send_msg, node_name, msg}, state) do
maybe_send_msg(node_name, msg, state)
{:noreply, state}
end
def handle_info(msg, state) do
IO.puts "MSG #{inspect msg}"
{:noreply, state}
end
def terminate(_reason, _state) do
:ok
end
defp maybe_send_msg(node_name, msg, nodes) do
node = Map.get(nodes, node_name)
pid = Node.spawn(node, Chat, :msg_loop, [])
send(pid, {:message, msg})
end
defp transform_node_name(nodes) do
Enum.map(nodes, fn node ->
name =
Atom.to_string(node)
|> String.split("@")
|> List.first()
{name, node}
end)
|> Enum.into(%{})
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment