diff options
Diffstat (limited to 'src/sd_notify.erl')
-rw-r--r-- | src/sd_notify.erl | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/src/sd_notify.erl b/src/sd_notify.erl index c5201da..c0bb824 100644 --- a/src/sd_notify.erl +++ b/src/sd_notify.erl @@ -29,23 +29,43 @@ -export([sd_notify/2, sd_notifyf/3, sd_pid_notify/3, sd_pid_notifyf/4, sd_pid_notify_with_fds/4]). --on_load(init/0). +-export([ready/0, reloading/0, stopping/0, watchdog/0]). +-export([start_link/0]). +-export([init/1, handle_info/2, terminate/2]). --define(nif_stub, nif_stub_error(?LINE)). +% API helpers -nif_stub_error(Line) -> - erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). +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">>, []). -init() -> - PrivDir = case code:priv_dir(?MODULE) of - {error, bad_name} -> - EbinDir = filename:dirname(code:which(?MODULE)), - AppPath = filename:dirname(EbinDir), - filename:join(AppPath, "priv"); - Path -> - Path - end, - erlang:load_nif(filename:join(PrivDir, ?MODULE) ++ "_drv", 0). +% 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, []). @@ -59,5 +79,20 @@ sd_notifyf(UnsetEnv, Format, Data) -> sd_pid_notifyf(Pid, UnsetEnv, Format, Data) -> sd_pid_notify_with_fds(Pid, UnsetEnv, lists:flatten(io_lib:format(Format, Data)), []). -sd_pid_notify_with_fds(_, _, _, _) -> - ?nif_stub. +sd_pid_notify_with_fds(_Pid, UnsetEnv, Call, _Fds) -> + error_logger:info_msg("systemd: ~p", [Call]), + case os:getenv("NOTIFY_SOCKET") of + false -> {error, not_configured}; + Path -> + case gen_udp:open(0, [local]) of + {error, SocketError} -> + {error, SocketError}; + {ok, Socket} -> + Result = gen_udp:send(Socket, {local,Path}, 0, Call), + gen_udp:close(Socket), + + UnsetEnv == true andalso os:unsetenv("NOTIFY_SOCKET"), + + Result + end + end. |