Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- defmodule EventWatcher do
- use Application
- def start(_type, _args) do
- import Supervisor.Spec, warn: false
- children = [
- worker(GenEvent, [[name: EventWatcher.GenEvent]], [id: :event_manager]),
- supervisor(EventWatcher.Watcher.Supervisor, [], [id: :watcher_supervisor])
- ]
- # `:rest_for_one` will restart watchers if event manager exits
- opts = [strategy: :rest_for_one, name: EventWatcher.Supervisor]
- Supervisor.start_link(children, opts)
- end
- end
- defmodule EventWatcher.Watcher.Supervisor do
- use Supervisor
- def start_link() do
- Supervisor.start_link(__MODULE__, nil, [name: __MODULE__])
- end
- def init(_) do
- default_handlers = [{EventWatcher.IO, :stdio}]
- handlers = Application.get_env(:event_watcher, :handlers, default_handlers)
- children = for {handler, args} <- handlers do
- # Watcher has `:id` matching handler so two watchers don't try to add the
- # same handler. `:restart` is `:transient` so a handler can remove itself
- # gracefully (see `:normal` stop below), other restarts can be valid too.
- worker(EventWatcher.Watcher, [handler, args], [id: handler, restart: :transient])
- end
- supervise(children, [strategy: :one_for_one])
- end
- end
- defmodule EventWatcher.Watcher do
- use GenServer
- def start_link(handler, args) do
- GenServer.start_link(__MODULE__, {handler, args})
- end
- def init({handler, args}) do
- case GenEvent.add_mon_handler(EventWatcher.GenEvent, handler, args) do
- :ok -> {:ok, handler}
- {:error, :ignore} -> :ignore # special case to ignore handler
- {:error, reason} -> exit({:failed_to_add_handler, handler, reason})
- end
- end
- def handle_info({:gen_event_EXIT, handler, reason}, handler) do
- {:stop, reason, handler}
- end
- end
- defmodule EventWatcher.IO do
- use GenEvent
- def handle_event(event, device) do
- IO.inspect(event)
- {:ok, device}
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement