From 0528181ea4ea54e4db21b6ddccf78d7287e57e85 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Tue, 7 Jul 2020 13:43:32 +0200 Subject: Add API proposed by Max Lapshin Signed-off-by: Peter Lemenkov --- src/sd_notify.erl | 38 ++++++++++++++++++++++++++++++++++++++ test/sd_notify_test.erl | 24 ++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/sd_notify.erl b/src/sd_notify.erl index 72f1324..c0bb824 100644 --- a/src/sd_notify.erl +++ b/src/sd_notify.erl @@ -29,6 +29,44 @@ -export([sd_notify/2, sd_notifyf/3, sd_pid_notify/3, sd_pid_notifyf/4, sd_pid_notify_with_fds/4]). +-export([ready/0, reloading/0, stopping/0, watchdog/0]). +-export([start_link/0]). +-export([init/1, handle_info/2, terminate/2]). + +% API helpers + +ready() -> sd_pid_notify_with_fds(0, false, <<"READY=1">>, []). +reloading() -> sd_pid_notify_with_fds(0, false, <<"RELOADING=1">>, []). +stopping() -> sd_pid_notify_with_fds(0, false, <<"STOPPING=1">>, []). +watchdog() -> sd_pid_notify_with_fds(0, false, <<"WATCHDOG=1">>, []). + +% gen_server API and callbacks + +start_link() -> + gen_server:start_link({local,?MODULE}, ?MODULE, [], []). + +init([]) -> + WatchdogMs = case os:getenv( "WATCHDOG_USEC" ) of + false -> none; + Value -> + Part = erlang:round(0.8 * erlang:list_to_integer(Value)), + erlang:convert_time_unit(Part, microsecond, millisecond) + end, + erlang:send_after(WatchdogMs, self(), watchdog), + error_logger:info_msg("watchdog: ~p ms", [WatchdogMs]), + {ok, WatchdogMs}. + +handle_info(watchdog, none) -> + {noreply, none}; +handle_info(watchdog, WatchdogMs) -> + watchdog(), + erlang:send_after(WatchdogMs, self(), watchdog), + {noreply, WatchdogMs}. + +terminate(_,_) -> ok. + +% Systemd API + sd_notify(UnsetEnv, Data) -> sd_pid_notify_with_fds(0, UnsetEnv, Data, []). diff --git a/test/sd_notify_test.erl b/test/sd_notify_test.erl index 21a9f9d..59df682 100644 --- a/test/sd_notify_test.erl +++ b/test/sd_notify_test.erl @@ -50,3 +50,27 @@ sd_notify_unsetenv_test_() -> ] }. + +sd_notify_watchdog_test_() -> + {ok, CWD} = file:get_cwd(), + FakeNotifyUnixSockName = CWD ++ "/fake-sock-" ++ integer_to_list(erlang:phash2(make_ref())), + {ok, FakeNotifyUnixSock} = gen_udp:open(0, [{ifaddr, {local, FakeNotifyUnixSockName}}, {active, false}, list]), + os:putenv("NOTIFY_SOCKET", FakeNotifyUnixSockName), + + {setup, + fun() -> ok end, + fun(_) -> ok = gen_udp:close(FakeNotifyUnixSock), ok = file:delete(FakeNotifyUnixSockName) end, + [ + { + "Try sending message", + fun() -> + os:putenv("WATCHDOG_USEC", "500000"), + sd_notify:start_link(), + {ok, {_Address, _Port, Packet}} = gen_udp:recv(FakeNotifyUnixSock, length("WATCHDOG=1"), 1000), + ?assertEqual("WATCHDOG=1", Packet) + end + } + + ] + + }. -- cgit v1.2.1