I use Task.Supervisor to handle incoming Datagrams for my UDP server. As a binary message comes in, it spawns a Task to process the datagram, if the decryption fails, or json parsing fails, no big deal, UDP server is still running.
Handling incoming datagrams…
def start_link(port) do
GenServer.start_link(__MODULE__, port, name: __MODULE__)
end
def init(port) do
Logger.info "Accepting datagrams on port:#{port}"
:gen_udp.open(port, [:binary, {:active, :true}])
end
def handle_info({udp, client_socket, client_addr, client_port, data}, state) do
{:ok, _pid} = Task.Supervisor.start_child(NodeBucket.TaskSupervisor, fn ->
process(client_socket, client_addr, client_port, data)
end)
{:noreply, state}
end
def process(socket, addr, port, data) do
IO.inspect addr
IO.inspect port
:ok = data
And the supervisor…
@mongo_database Application.get_env(:node_bucket, :mongo_database)
@mongo_host Application.get_env(:node_bucket, :mongo_host)
@port Application.get_env(:node_bucket, :port)
def start_link do
Supervisor.start_link(__MODULE__, :ok, name: @name)
end
def init(:ok) do
children = [
supervisor(Task.Supervisor, [[name: NodeBucket.TaskSupervisor]]),
NodeBucket.Instream.child_spec,
worker(MongoPool, [[hostname: @mongo_host, database: @mongo_database, max_overflow: 10, size: 5]]),
worker(NodeBucket.UDPServer, [@port])
]
supervise(children, strategy: :one_for_one)
end
end