View Source Rivet.Utils.Interval.TickHF (rivet_utils v2.0.3)
High frequency interval tick - forced process state matching the interval's desired structure (optimal tuple instead of dict). Runs as an independent GenServer process. Send "state data" into GenServer.start_link(state_data)
How to use:
use Utils.IntervalTickHF, [opts]
(see below for options)define function
callback_name
which is called every frequency, with an extra option of:tick
, and every interval with the option being:tock
. Spec:callback_name(
state_data :: term(), :tick | :tock, last_run_time :: number()
) :: {:ok, state_data :: term()}
Opts include:
callback: atom()
— REQUIRED — function to call on each interval/frequencytick: number()
— REQUIRED - integer in the time_size matching get_time.tick must be smaller than tock. (i.e. 100 vs 1000).
tock: number()
— REQUIRED - integer in the time_size matching get_timetock must be large than tick.
get_time: fn()
— how time is measured; defaults toSystem.system_time(:second)
millis_factor: 1000
— a multiplier to convert time from get_time into millis.handle_interval: :hf_interval_tick
— change the handle_info(:callback, ..) name — largely unecessary to adjust unless the default :hf_interval_tick collides with something else already being in handle_info(..)
Example:
defmodule SensorReader do
use IntervalTickHF,
callback: :sample_power,
get_time: System.system_time(:millisecond),
interval: 1000,
frequency: 10,
millis_factor: 1
def sample_power({config, samples}, :tick, _) do
{:ok, {config, [read_value(config) | samples]}}
end
def sample_power({config, samples}, :tock, _) do
Report.Value.somehow( [read_value(config) | samples] |> normalize_samples())
{:ok, {config, []}}
end
defp read_value(config), do: ...
defp normalize_samples(samples), do: ...
end
Started with:
SensorReader.start_link({%{config_data_here}, []}, name: :the_sensor)
Contributor: Brandon Gillespie
Summary
Types
@type interval_state() :: {state_data :: any(), next_tock :: time_number(), last_tick :: time_number(), timer_ref :: reference()}
@type time_number() :: integer()