Description
This was originally posted on slack - I have copy pasted the question.
--
getting the current value + timestamp of alarms I am subscribed to
After subscribing to an alarm I need to query for the current state of that alarm in case it was set before I subscribed. My use case is pushing active alarms on a device up to a backend so they can be shown in a UI - the data for the server needs to include the timestamp when the event occurred. I cannot see a way to do this without diving into PropertyTable
. My current code looks something like:
defmodule AlarmNotifier do
use GenServer
def init(_opts) do
# NOTE: :_ is between 1 and 36
:ok = Alarmist.subscribe({SlotOutOfStockAlarm, :_})
events =
for {alarm_id, desc, level} <- PropertyTable.match(Alarmist, {SlotOutOfStockAlarm, :_}) do
# NOTE: This is a race condition waiting to happen...
{:ok, {:set, _desc, _level}, mono} = PropertyTable.fetch_with_timestamp(Alarmist, alarm_id)
%Alarmist.Event{
id: alarm_id,
state: :set,
description: desc,
level: level,
timestamp: mono,
previous_state: :clear,
previous_timestamp: mono
}
end
{:ok, Enum.reduce(events, %{}, &handle_event/2)}
end
def handle_info(%Alarmist.Event{state: :set} = event, state) do
{:noreply, handle_event(event, state)}
end
defp handle_event(event, state) do
duration_native = System.monotonic_time() - timestamp
duration_milli = System.convert_time_unit(duration_native, :native, :millisecond)
raised_at = DateTime.add(DateTime.utc_now(), duration_milli, :millisecond)
# TODO: real implementation
# Socket.push(%{alarm_id: event.id, raised_at: raised_at})
state
end
end
I have seen Alarmist.get_alarms/0
and Alarmist.get_alarm_ids
but both of these return all the active alarms which is more than I am interested in. From what I can see subscribing doesn't send a message with the current data either.