Current section

Files

Jump to
snowhite lib modules clock server.ex
Raw

lib/modules/clock/server.ex

defmodule Snowhite.Modules.Clock.Server do
@moduledoc """
Atomic clock server that syncs the time between clock modules.
It ticks every seconds and updates itself
"""
use GenServer
import Snowhite.Helpers.Timing
require Logger
@auto_sync_timer ~d(1s)
@fallback_timezone "UTC"
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end
def now do
GenServer.call(__MODULE__, :now)
end
def date do
__MODULE__
|> GenServer.call(:now)
|> Timex.to_date()
end
def init(options) do
Logger.info("[#{__MODULE__}] Started (#{inspect(options)})")
Process.send_after(self(), :auto_sync, @auto_sync_timer)
{:ok, update(%{options: options, time: nil})}
end
def handle_cast(:update, state) do
send(self(), :notify)
{:noreply, update(state)}
end
def handle_call(:now, _, %{time: time} = state) do
{:reply, time, state}
end
def handle_info(:auto_sync, state) do
state = update(state)
Process.send_after(self(), :auto_sync, @auto_sync_timer)
send(self(), :notify)
{:noreply, state}
end
def handle_info(:notify, state) do
Phoenix.PubSub.broadcast!(Snowhite.PubSub, "snowhite:modules:clock", :updated)
{:noreply, state}
end
defp update(%{options: options} = state) do
time = now(options)
%{state | time: time}
end
defp now(options) do
options
|> Keyword.get(:timezone, @fallback_timezone)
|> Timex.now()
end
end