Current section

Files

Jump to
exticker lib exticker.ex
Raw

lib/exticker.ex

defmodule ExTicker do
@moduledoc """
Simple Elixir ticker
Basic usage:
```elixir
defmodule MyWorker do
use ExTicker, interval: 1000, do: :work
def work() do
# .. do some stuff ...
end
end
```
Module APIs:
```
MyWorker.start()
MyWorker.stop()
```
"""
defmacro __using__(opt) do
intv = Keyword.get(opt, :interval, 1000)
work_fn = Keyword.get(opt, :do, :work)
quote do
use GenServer
@me __MODULE__
@interval unquote(intv)
@work_fn unquote(work_fn)
@doc """
start it
"""
def start() do
Kernel.send(@me, {:update, :running})
end
@doc """
stop it
"""
def stop() do
Kernel.send(@me, {:update, :stopped})
end
########################
## implement GenServer
##
def start_link(args) do
GenServer.start_link(@me, args, name: @me)
end
@impl GenServer
def init(_) do
{:ok, :init}
end
@impl GenServer
def handle_info({:work}, state) when state == :running do
apply(@me, @work_fn, [])
Process.send_after(@me, {:work}, @interval)
{:noreply, state}
end
@impl GenServer
def handle_info({:work}, state) do
{:noreply, state}
end
@impl GenServer
def handle_info({:update, new_state}, state)
when state != :running and new_state == :running do
Process.send_after(@me, {:work}, @interval)
{:noreply, new_state}
end
@impl GenServer
def handle_info({:update, new_state}, _state) do
{:noreply, new_state}
end
@impl GenServer
def handle_call(_request, _from, state) do
{:reply, "meaningless call", state}
end
end
end
end