summaryrefslogtreecommitdiff
path: root/src/sd_notify.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/sd_notify.erl')
-rw-r--r--src/sd_notify.erl67
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.