Current section
Files
Jump to
Current section
Files
lib/grains/debug_timer.ex
defmodule Grains.DebugTimer do
@moduledoc """
Debug version of `Grains.Timer`.
To replace the normal Timer with this, start you bread like this:
```
recipe = Recipe.new(:Periodic, %{
Source => Grains.periodic(Sink, 10, %{with_timestamps: true}),
})
grains = Grains.new(%{
Source => {Source, %{}, []},
Sink => {Sink, %{}, []},
Source.Timer.Sink => {Grains.DebugTimer, [], []}
})
{:ok, bread} = Grains.Supervisor.start_link(recipe, grains, id: Test)
debug_timer = Grains.get_name(bread, Source.Timer.Sink)
send(debug_timer, :tick)
```
## With Timestamps
Similarly to `Grains.Timer`, the debug timer accepts an option `with_timestamps`. If set to
true, the `:tick` must include a timestamp, which is then used when forwarding the received
message downstream. If `with_timestamps` is not set, the `:tick` must not include a timestamp,
and the message is forwarded as-is.
"""
use Grains.GenGrain
alias Grains.Timer
defdelegate name(left, grain), to: Timer
defmodule State do
defstruct timestamp: nil, with_timestamps: false
end
def init(opts) do
state = struct!(State, Map.take(opts, %State{} |> Map.keys()))
{:ok, state}
end
def handle_info(:tick, state = %State{with_timestamps: false}) do
pull()
{:noreply, state}
end
def handle_info({:tick, ts}, state = %State{with_timestamps: true}) do
state = %State{state | timestamp: ts}
pull()
{:noreply, state}
end
def handle_push(msg, _from, state) do
if state.with_timestamps do
now = state.timestamp
:ok = push({now, msg})
else
push(msg)
end
{:noreply, state}
end
def handle_pull(_from, state) do
pull()
{:noreply, state}
end
end