Packages
honeydew
1.0.1
1.5.0
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc7
1.0.0-rc6
1.0.0-rc5
1.0.0-rc4
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Pluggable local/clusterable job queue focused on safety.
Current section
Files
Jump to
Current section
Files
lib/honeydew/dispatcher/lru_node.ex
defmodule Honeydew.Dispatcher.LRUNode do
alias Honeydew.Dispatcher.LRU
# TODO: docs
def init do
# {node_queue, workers}
{:ok, {:queue.new, Map.new}}
end
def available?({_node_queue, workers}) do
workers
|> Map.values
|> Enum.any?(&LRU.available?/1)
end
def check_in(worker, {node_queue, workers}) do
node = worker_node(worker)
{node_queue, node_workers} =
workers
|> Map.get(node)
|> case do
nil ->
# this node isn't currently known
{:ok, node_workers} = LRU.init
{:queue.in(node, node_queue), node_workers}
node_workers ->
# there's already at least one worker from this node present
{node_queue, node_workers}
end
{node_queue, Map.put(workers, node, LRU.check_in(worker, node_workers))}
end
def check_out(job, {node_queue, workers} = state) do
with {{:value, node}, node_queue} <- :queue.out(node_queue),
%{^node => node_workers} <- workers,
{worker, node_workers} when not is_nil(worker) <- LRU.check_out(job, node_workers) do
if :queue.is_empty(node_workers) do
{worker, {node_queue, Map.delete(workers, node)}}
else
{worker, {:queue.in(node, node_queue), Map.put(workers, node, node_workers)}}
end
else _ ->
{nil, state}
end
end
def remove(worker, {node_queue, workers}) do
node = worker_node(worker)
with %{^node => node_workers} <- workers,
node_workers <- LRU.remove(worker, node_workers) do
if LRU.available?(node_workers) do
{node_queue, Map.put(workers, node, node_workers)}
else
{:queue.filter(&(&1 != node), node_queue), Map.delete(workers, node)}
end
else _ ->
# this means that we've been asked to remove a worker we don't know about
# this should never happen :o
{node_queue, workers}
end
end
# for testing
defp worker_node({_worker, node}), do: node
defp worker_node(worker) do
:erlang.node(worker)
end
end