Current section
Files
Jump to
Current section
Files
lib/exticker.ex
defmodule ExTicker do
@moduledoc """
Simple Elixir ticker.
Basic usage:
```elixir
defmodule MyTicker do
# must provide 3 options in order:
# init_wait -> time to start in the beginning (ms)
# interval -> interval (ms)
# do -> refer to custom function to trigger
use ExTicker, init_wait: 0, interval: 1000, do: :work
def work() do
# .. do some stuff ...
# returning :ok -> contine ad infinitum
:ok
# returning others -> quit, e.g:
# :quit
end
end
```
"""
defmacro __using__(opt) do
[init_wait: init_w, interval: intv, do: work_fn] = opt
quote do
use GenServer
@me __MODULE__
@init_wait unquote(init_w)
@interval unquote(intv)
@work_fn unquote(work_fn)
@doc """
print current module name
"""
def whoami() do
@me
end
@doc """
print opts
"""
def opts() do
%{
:init_wait => @init_wait,
:interval => @interval,
:work_fn => @work_fn
}
end
@doc """
invoke work function (pointed by :do) once
"""
def invoke(args) do
apply(@me, @work_fn, args)
end
def start_link(args) do
GenServer.start_link(@me, args, name: @me)
end
@impl GenServer
def init(arg) do
:timer.sleep(@init_wait)
schedule()
{:ok, arg}
end
@impl GenServer
def handle_info({:work}, state) do
case invoke([]) do
:ok ->
schedule()
_ ->
nil
end
{:noreply, state}
end
def schedule() do
Process.send_after(@me, {:work}, @interval)
end
@impl GenServer
def handle_call(_request, _from, state) do
{:reply, "meaningless call", state}
end
end
end
end