Skip to content

Commit

Permalink
Change Verk.Supervisor to start new ManagerSupervisor
Browse files Browse the repository at this point in the history
The ManagerSupervisor will guarantee that the Manager exists before the
queues
  • Loading branch information
edgurgel committed Sep 2, 2017
1 parent 0c6801a commit aa9c3ed
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 22 deletions.
17 changes: 17 additions & 0 deletions lib/verk/manager_supervisor.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Verk.Manager.Supervisor do
@moduledoc false
use Supervisor

@doc false
def start_link, do: Supervisor.start_link(__MODULE__, [], name: __MODULE__)

@doc false
def init(_) do
queues = Confex.get_env(:verk, :queues, [])
children = for {queue, size} <- queues, do: Verk.Queue.Supervisor.child_spec(queue, size)

children = [worker(Verk.Manager, [queues], id: Verk.Manager) | children]

supervise(children, strategy: :rest_for_one)
end
end
29 changes: 10 additions & 19 deletions lib/verk/supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,38 @@ defmodule Verk.Supervisor do
"""
use Supervisor

@doc false
@doc """
It starts the main supervisor
"""
def start_link do
Supervisor.start_link(__MODULE__, [], name: __MODULE__)
end

@doc false
def init(_) do
queues = Confex.get_env(:verk, :queues, [])
children = for {queue, size} <- queues, do: queue_child(queue, size)

redis_url = Confex.get_env(:verk, :redis_url)

redis = worker(Redix, [redis_url, [name: Verk.Redis]], id: Verk.Redis)
event_producer = worker(Verk.EventProducer, [], id: Verk.EventProducer)
queue_stats = worker(Verk.QueueStats, [], id: Verk.QueueStats)
schedule_manager = worker(Verk.ScheduleManager, [], id: Verk.ScheduleManager)
event_producer = worker(Verk.EventProducer, [])

queue_stats = worker(Verk.QueueStats, [])
redis = worker(Redix, [redis_url, [name: Verk.Redis]], id: Verk.Redis)
manager_sup = supervisor(Verk.Manager.Supervisor, [], id: Verk.Manager.Supervisor)

children = [redis, event_producer, queue_stats, schedule_manager] ++ children
children = [redis, event_producer, queue_stats, schedule_manager, manager_sup]
supervise(children, strategy: :one_for_one)
end

@doc false
def start_child(queue, size \\ 25) when is_atom(queue) and size > 0 do
Supervisor.start_child(__MODULE__, queue_child(queue, size))
Supervisor.start_child(__MODULE__, Verk.Queue.Supervisor.child_spec(queue, size))
end

@doc false
def stop_child(queue) when is_atom(queue) do
name = supervisor_name(queue)
name = Verk.Queue.Supervisor.name(queue)
case Supervisor.terminate_child(__MODULE__, name) do
:ok -> Supervisor.delete_child(__MODULE__, name)
error = {:error, :not_found} -> error
end
end

defp queue_child(queue, size) when is_atom(queue) do
supervisor(Verk.Queue.Supervisor, [queue, size], id: supervisor_name(queue))
end

defp supervisor_name(queue) do
String.to_atom("#{queue}.supervisor")
end
end
14 changes: 14 additions & 0 deletions test/manager_supervisor_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule Verk.ManagerSupervisorTest do
use ExUnit.Case
import Verk.Manager.Supervisor

describe "init/1" do
test "defines tree" do
{:ok, {_, children}} = init([])
[manager, default] = children

assert {Verk.Manager, _, _, _, :worker, [Verk.Manager]} = manager
assert {:"default.supervisor", _, _, _, :supervisor, [Verk.Queue.Supervisor]} = default
end
end
end
61 changes: 58 additions & 3 deletions test/supervisor_test.exs
Original file line number Diff line number Diff line change
@@ -1,16 +1,71 @@
defmodule Verk.SupervisorTest do
use ExUnit.Case
import :meck
import Verk.Supervisor

setup do
new Supervisor
on_exit fn -> unload() end
:ok
end

describe "init/1" do
test "defines tree" do
{:ok, {_, children}} = Verk.Supervisor.init([])
[redix, producer, stats, schedule_manager, default] = children
{:ok, {_, children}} = init([])
[redix, producer, stats, schedule_manager, manager_sup] = children

assert {Verk.Redis, _, _, _, :worker, [Redix]} = redix
assert {Verk.EventProducer, _, _, _, :worker, [Verk.EventProducer]} = producer
assert {Verk.QueueStats, _, _, _, :worker, [Verk.QueueStats]} = stats
assert {Verk.ScheduleManager, _, _, _, :worker, [Verk.ScheduleManager]} = schedule_manager
assert {:"default.supervisor", _, _, _, :supervisor, [Verk.Queue.Supervisor]} = default
assert {Verk.Manager.Supervisor, _, _, _, :supervisor, [Verk.Manager.Supervisor]} = manager_sup
end
end

describe "start_child/2" do
test "add a new queue" do
queue = :test_queue

child = { :"test_queue.supervisor", { Verk.Queue.Supervisor, :start_link, [:test_queue, 30] }, :permanent, :infinity, :supervisor, [ Verk.Queue.Supervisor ] }
expect(Supervisor, :start_child, [Verk.Supervisor, child], :ok)

assert start_child(queue, 30) == :ok

assert validate Supervisor
end
end

describe "stop_child/1" do
test "a queue successfully" do
queue = :test_queue

expect(Supervisor, :terminate_child, [Verk.Supervisor, :"test_queue.supervisor"], :ok)
expect(Supervisor, :delete_child, [Verk.Supervisor, :"test_queue.supervisor"], :ok)

assert stop_child(queue) == :ok

assert validate Supervisor
end

test "a queue unsuccessfully terminating child" do
queue = :test_queue

expect(Supervisor, :terminate_child, [Verk.Supervisor, :"test_queue.supervisor"], { :error, :not_found })

assert stop_child(queue) == { :error, :not_found }

assert validate Supervisor
end

test "a queue unsuccessfully deleting child" do
queue = :test_queue

expect(Supervisor, :terminate_child, [Verk.Supervisor, :"test_queue.supervisor"], :ok)
expect(Supervisor, :delete_child, [Verk.Supervisor, :"test_queue.supervisor"], { :error, :not_found })

assert stop_child(queue) == { :error, :not_found }

assert validate Supervisor
end
end
end

0 comments on commit aa9c3ed

Please sign in to comment.