-
Notifications
You must be signed in to change notification settings - Fork 266
/
estop_timer.ex
74 lines (62 loc) · 1.75 KB
/
estop_timer.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
defmodule Farmbot.Firmware.EstopTimer do
@moduledoc """
Module responsible for timing emails about E stops.
"""
use GenServer
use Farmbot.Logger
@msg "Farmbot has been E-Stopped for more than 10 minutes."
# Ten minutes.
@timer_ms 600_000
# fifteen seconds.
# @timer_ms 15000
@doc "Checks if the timer is active."
def timer_active? do
GenServer.call(__MODULE__, :timer_active?)
end
@doc "Starts a new timer if one isn't started."
def start_timer do
GenServer.call(__MODULE__, :start_timer)
end
@doc "Cancels a timer if it exists."
def cancel_timer do
GenServer.call(__MODULE__, :cancel_timer)
end
@doc false
def start_link do
GenServer.start_link(__MODULE__, [], [name: __MODULE__])
end
@doc false
def init([]) do
{:ok, %{timer: nil, already_sent: false}}
end
def handle_call(:timer_active?, _, state) do
{:reply, is_timer_active?(state.timer), state}
end
def handle_call(:start_timer, _from, state) do
if is_timer_active?(state.timer) do
{:reply, :ok, state}
else
{:reply, :ok, %{state | timer: do_start_timer(self())}}
end
end
def handle_call(:cancel_timer, _from, state) do
if is_timer_active?(state.timer) do
Process.cancel_timer(state.timer)
end
{:reply, :ok, %{state | timer: nil, already_sent: false}}
end
def handle_info(:timer, state) do
if state.already_sent do
{:noreply, %{state | timer: nil}}
else
Logger.warn 1, @msg, [channels: [:fatal_email]]
{:noreply, %{state | timer: nil, already_sent: true}}
end
end
defp is_timer_active?(timer) do
if timer, do: is_number(Process.read_timer(timer)), else: false
end
defp do_start_timer(pid) do
Process.send_after(pid, :timer, @timer_ms)
end
end