-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #137 from edgurgel/verk-manager
Verk manager
- Loading branch information
Showing
11 changed files
with
267 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
defmodule Verk.Manager do | ||
@moduledoc """ | ||
A process that manages the state of each started queue | ||
""" | ||
|
||
use GenServer | ||
require Logger | ||
|
||
@table :verk_manager | ||
@ets_options [:ordered_set, :named_table, :public, read_concurrency: true] | ||
|
||
@doc false | ||
def start_link(queues), do: GenServer.start_link(__MODULE__, queues, name: __MODULE__) | ||
|
||
@doc false | ||
def init(queues) do | ||
ets = :ets.new(@table, @ets_options) | ||
for {queue, size} <- queues, do: :ets.insert_new(@table, {queue, size}) | ||
{:ok, ets} | ||
end | ||
|
||
@doc """ | ||
It returns the status of each queue currently | ||
[{:default, 25}, {:low_priority, 10}] | ||
""" | ||
@spec status :: [{atom, pos_integer}] | ||
def status, do: :ets.tab2list(@table) | ||
|
||
@doc """ | ||
It adds the `queue` running with the amount of `size` of workers | ||
It always returns the child spec | ||
""" | ||
@spec add(atom, pos_integer) :: Supervisor.on_start_child | ||
def add(queue, size) do | ||
unless :ets.insert_new(@table, {queue, size}) do | ||
Logger.error "Queue #{queue} is already running" | ||
end | ||
Verk.Supervisor.start_child(queue, size) | ||
end | ||
|
||
@doc """ | ||
It removes the `queue` | ||
It returns `:ok` if successful and `{:error, :not_found}` otherwise | ||
""" | ||
@spec remove(atom) :: :ok | {:error, :not_found} | ||
def remove(queue) do | ||
:ets.delete(@table, queue) | ||
Verk.Supervisor.stop_child(queue) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
defmodule Verk.ManagerTest do | ||
use ExUnit.Case | ||
import :meck | ||
import Verk.Manager | ||
|
||
setup do | ||
new Verk.Supervisor | ||
on_exit fn -> unload() end | ||
:ok | ||
end | ||
|
||
describe "init/1" do | ||
test "creates an ETS table with queues" do | ||
queues = [default: 25, low_priority: 10] | ||
init(queues) | ||
assert :ets.tab2list(:verk_manager) == queues | ||
end | ||
end | ||
|
||
describe "status/0" do | ||
test "returns running queues" do | ||
queues = [default: 25, low_priority: 10] | ||
init(queues) | ||
assert status() == queues | ||
end | ||
end | ||
|
||
describe "add/2" do | ||
test "adds queue to supervisor if not already there" do | ||
init([]) | ||
|
||
expect(Verk.Supervisor, :start_child, [:default, 25], {:ok, :child}) | ||
|
||
assert add(:default, 25) == {:ok, :child} | ||
assert :ets.tab2list(:verk_manager) == [default: 25] | ||
assert validate Verk.Supervisor | ||
end | ||
end | ||
|
||
describe "remove/1" do | ||
test "removes queue from supervisor if queue is running" do | ||
queues = [default: 25] | ||
init(queues) | ||
|
||
expect(Verk.Supervisor, :stop_child, [:default], :ok) | ||
|
||
assert remove(:default) == :ok | ||
assert validate Verk.Supervisor | ||
end | ||
|
||
test "does nothing if queue is not running" do | ||
queues = [default: 25] | ||
init(queues) | ||
|
||
expect(Verk.Supervisor, :stop_child, [:default], {:error, :not_found}) | ||
|
||
assert remove(:default) == {:error, :not_found} | ||
assert validate Verk.Supervisor | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
defmodule Verk.QueueSupervisorTest do | ||
use ExUnit.Case | ||
import Verk.Queue.Supervisor | ||
|
||
describe "init/1" do | ||
test "defines tree" do | ||
{:ok, {_, children}} = init([:default, 25]) | ||
[queue_manager, pool, workers_manager] = children | ||
|
||
assert {:"default.queue_manager", _, _, _, :worker, [Verk.QueueManager]} = queue_manager | ||
assert {:"default.pool", _, _, _, :worker, [:poolboy]} = pool | ||
assert {:"default.workers_manager", _, _, _, :worker, [Verk.WorkersManager]} = workers_manager | ||
end | ||
end | ||
|
||
describe "name/1" do | ||
test "returns supervisor name" do | ||
assert name("default") == :"default.supervisor" | ||
end | ||
end | ||
|
||
describe "child_spec/2" do | ||
test "returns supervisor spec" do | ||
assert {:"default.supervisor", | ||
{Verk.Queue.Supervisor, :start_link, [:default, 25]}, _, | ||
_, :supervisor, [Verk.Queue.Supervisor]} = child_spec(:default, 25) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.