Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
86 lines (71 sloc) 1.96 KB
#
# The MIT License (MIT)
#
# Copyright (c) 2014-2015 Undead Labs, LLC
#
defmodule Discovery.Heartbeat do
use GenServer
@retry_ms 5000
@spec start_link(binary, integer) :: GenServer.on_start
def start_link(check_id, interval) do
GenServer.start_link(__MODULE__, [check_id, interval])
end
@spec start(binary, integer) :: GenServer.on_start
def start(check_id, interval) do
GenServer.start(__MODULE__, [check_id, interval])
end
@spec stop(pid) :: :ok
def stop(pid) do
GenServer.call(pid, :stop)
end
#
# Private API
#
defp send_pulse(check_id) do
{result, _} = Consul.Agent.Check.pass(check_id)
result
end
defp service_name(check_id) when is_binary(check_id) do
case String.split(check_id, ":", parts: 2) do
["service", name] ->
{:ok, name}
_ ->
{:error, :invalid_check_id}
end
end
#
# GenServer callbacks
#
def init([check_id, interval]) do
case service_name(check_id) do
{:ok, service} ->
:ok = Discovery.register_app(service)
:ok = Discovery.Directory.add(Node.self, service)
{:ok, %{timer: nil, check_id: check_id, interval: interval, service: service}, 0}
error ->
{:stop, error}
end
end
def handle_info(:timeout, %{check_id: check_id, interval: interval} = state) do
case send_pulse(check_id) do
:ok ->
timer = :erlang.send_after(interval, self, :pulse)
{:noreply, %{state | timer: timer}}
:error ->
{:noreply, state, @retry_ms}
end
end
def handle_info(:pulse, %{check_id: check_id, interval: interval, timer: timer} = state) do
:erlang.cancel_timer(timer)
send_pulse(check_id)
new_timer = :erlang.send_after(interval, self, :pulse)
{:noreply, %{state | timer: new_timer}}
end
def handle_call(:stop, _, state) do
{:stop, :normal, :ok, state}
end
def terminate(_, %{service: service}) do
Discovery.Directory.drop(Node.self, service)
:ok
end
end