Packages
tarearbol
0.13.2
1.12.0
1.11.2
1.11.1
1.11.0
1.10.4
1.10.3
1.10.2
1.10.0
1.9.102
1.9.101
1.9.100
1.9.99
1.9.11
1.9.10
1.9.9
1.9.8
1.9.7
1.9.6
1.9.5
1.9.4
1.9.3
1.9.2
1.9.1
1.9.0
1.8.2
1.8.1
1.8.0
1.7.0
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.0
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.4
1.0.3
1.0.2
1.0.0
0.99.11
0.99.10
0.99.9
0.99.8
0.99.7
0.99.6
0.99.4
0.99.3
0.99.2
0.99.1
0.99.0
0.14.1
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.0
0.9.6
0.9.5
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.0
The supervised tree of tasks, simplifying the process of handling: - recurrent tasks - retried tasks - long tasks - etc
Current section
Files
Jump to
Current section
Files
lib/tarearbol/extras/cron.ex
defmodule Tarearbol.Cron do
@moduledoc false
use GenServer
require Logger
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
def init(_opts) do
{:ok, table} = :dets.open_file(:tarearbol, type: :set)
table
|> tasks!()
|> Enum.each(fn {{m, f, a}, t, o} ->
Tarearbol.Errand.run_at({m, f, a}, t, o)
end)
{:ok, table}
end
def terminate(_reason, table), do: :dets.close(table)
#############################################################################
def jobs, do: GenServer.call(__MODULE__, :tasks)
def clear!, do: GenServer.call(__MODULE__, :clear)
def put_task({{_mod, _fun, _args}, _time, _opts} = task),
do: GenServer.call(__MODULE__, {:put_task, task})
def put_task({fun, _time, _opts} = task) when is_function(fun),
do: GenServer.call(__MODULE__, {:not_supported, task})
def del_task({{_mod, _fun, _args}, _time, _opts} = task),
do: GenServer.call(__MODULE__, {:del_task, task})
def del_task({fun, _time, _opts} = task) when is_function(fun),
do: GenServer.call(__MODULE__, {:not_supported, task})
#############################################################################
def handle_call(:tasks, _from, table), do: {:reply, tasks!(table), table}
def handle_call(:clear, _from, table) do
cleared = tasks!(table)
:dets.insert(table, {:tasks, []})
{:reply, cleared, table}
end
def handle_call({:not_supported, task}, _from, table) do
Logger.error("Inplace functions are not supported. Got [#{inspect(task)}].")
{:reply, task, table}
end
def handle_call({:put_task, {{_mod, _fun, _args}, _time, _opts} = task}, _from, table) do
reply = [task | do_delete(task, table)]
:dets.insert(table, {:tasks, reply})
{:reply, reply, table}
end
def handle_call({:del_task, {{_mod, _fun, _args}, _time, _opts} = task}, _from, table) do
reply = do_delete(task, table)
:dets.insert(table, {:tasks, reply})
{:reply, reply, table}
end
#############################################################################
defp do_delete({{mod, fun, args}, time, opts}, table) do
table
|> tasks!()
|> Enum.filter(fn {{m, f, a}, t, o} ->
DateTime.diff(t, time, :microsecond) >= 1_000 || m != mod || f != fun || a != args ||
Enum.sort(o) != Enum.sort(opts)
end)
end
defp tasks!(table) do
case :dets.lookup(table, :tasks) do
{:error, _reason} ->
:dets.insert(table, {:tasks, []})
[]
[] ->
:dets.insert(table, {:tasks, []})
[]
tasks ->
tasks[:tasks]
end
end
end