Skip to content

Commit

Permalink
WIP - make handlers more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
pavlos committed Apr 10, 2016
1 parent 64e751b commit 38cf0d3
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 19 deletions.
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ use Mix.Config
#
# import_config "#{Mix.env}.exs"

config :tachometer, poll_interval: 1000
config :tachometer, poll_interval: 5000
4 changes: 4 additions & 0 deletions lib/tachometer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ defmodule Tachometer do
Tachometer.Supervisor.supervise_event_handler Tachometer.SchedulerUsageEventManager, handler_module
end

def remove_scheduler_usage_handler(handler_module) do
Tachometer.Supervisor.terminate_event_handler handler_module
Tachometer.Supervisor.delete_event_handler handler_module
end
end
8 changes: 0 additions & 8 deletions lib/tachometer/scheduler_usage_event_manager.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ defmodule Tachometer.SchedulerUsageEventManager do
GenEvent.notify __MODULE__, {:scheduler_usage_update, scheduler_usage}
end

def add_handler(handler) do
GenEvent.add_handler __MODULE__, handler, nil
end

def delete_handler(handler) do
GenEvent.remove_handler __MODULE__, handler, nil
end

def which_handlers do
GenEvent.which_handlers __MODULE__
end
Expand Down
10 changes: 9 additions & 1 deletion lib/tachometer/supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ defmodule Tachometer.Supervisor do
end

def supervise_event_handler(manager, handler_module) do
watcher_spec = worker(Watcher, [Tachometer.SchedulerUsageEventManager, handler_module, []])
watcher_spec = worker(Watcher, [manager, handler_module, []], [id: handler_module])
Supervisor.start_child __MODULE__, watcher_spec
end

def terminate_event_handler(handler_module) do
Supervisor.terminate_child __MODULE__, handler_module
end

def delete_event_handler(handler_module) do
Supervisor.delete_child __MODULE__, handler_module
end

def stop do
Supervisor.stop(__MODULE__, :normal)
end
Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
%{"watcher": {:hex, :watcher, "1.0.0"}}
64 changes: 55 additions & 9 deletions test/event_handling_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ defmodule EventHandlingTest do
use ExUnit.Case, async: false
alias Tachometer.SchedulerUsageEventManager
require TestHandlerMacro
import ExUnit.CaptureLog


@poll_interval 30
@receive_wait @poll_interval + 5

setup_all do
:timer.sleep 10
Expand All @@ -14,7 +17,8 @@ defmodule EventHandlingTest do
setup do
on_exit fn ->
SchedulerUsageEventManager.which_handlers |>
Enum.map(&SchedulerUsageEventManager.delete_handler/1)
Enum.map(&Tachometer.remove_scheduler_usage_handler/1)
flush()
end
end

Expand All @@ -27,18 +31,60 @@ defmodule EventHandlingTest do
end
end

SchedulerUsageEventManager.add_handler(TestHandlerUsage)
{:ok, _handler} = Tachometer.add_scheduler_usage_handler(TestHandlerUsage)
:timer.sleep @poll_interval * 3
end

test "event handler gets called" do
self |>
TestHandlerMacro.create_test_handler(TestHandlerCalled) |>
SchedulerUsageEventManager.add_handler
test "event handler gets called and then deleted" do
handler_name = TestHandlerCalled
{:ok, _handler} = create_messaging_handler(handler_name)

assert_receive :scheduler_usage_update_received_by_TestSchedulerUsageEventHandler, @receive_wait
:ok = Tachometer.remove_scheduler_usage_handler handler_name
assert [] == Tachometer.SchedulerUsageEventManager.which_handlers
refute_receive :scheduler_usage_update_received_by_TestSchedulerUsageEventHandler, @receive_wait
end

test "that handlers can survive an event manager crash" do
capture_log fn ->
{:ok, _handler} = create_messaging_handler(TestHandlerManagerKill)
pid = Process.whereis(Tachometer.SchedulerUsageEventManager)

# crash the event manager
Process.exit(pid, :kill)
:timer.sleep 10

assert [TestHandlerManagerKill] == Tachometer.SchedulerUsageEventManager.which_handlers
assert_receive :scheduler_usage_update_received_by_TestSchedulerUsageEventHandler, @receive_wait
end
end

assert_receive :scheduler_usage_update_received_by_TestSchedulerUsageEventHandler, @poll_interval + 5
SchedulerUsageEventManager.delete_handler(TestSchedulerUsageEventHandler)
refute_receive :event_reveived, @poll_interval * 3
test "that handlers can survive a bad notify" do
{:ok, _handler} = create_messaging_handler(TestHandlerBadNotify)
GenEvent.notify(Tachometer.SchedulerUsageEventManager, :bogus_event)
flush()
assert_receive :scheduler_usage_update_received_by_TestSchedulerUsageEventHandler, @receive_wait
end

test "that handlers can survive a bad call" do
{:ok, _handler} = create_messaging_handler(TestHandlerBadCall)
GenEvent.call(Tachometer.SchedulerUsageEventManager, TestHandlerBadCall, :bogus_call)
flush()
assert_receive :scheduler_usage_update_received_by_TestSchedulerUsageEventHandler, @receive_wait
end

defp create_messaging_handler(name) do
{:ok, _handler} = self |>
TestHandlerMacro.create_test_handler(name) |>
Tachometer.add_scheduler_usage_handler
end

defp flush do
receive do
_ -> flush
after
0 -> :ok
end
end

end

0 comments on commit 38cf0d3

Please sign in to comment.