zx/zomp/lib/otpr-zx/0.1.0/src/zx_daemon.erl

73 lines
2.6 KiB
Erlang

%%% @doc
%%% ZX Daemon
%%%
%%% Resident execution daemon and runtime interface to Zomp.
%%% @end
-module(zx_daemon).
-export([]).
%%% App execution loop
-spec exec_wait(State) -> no_return()
when State :: state().
%% @private
%% Execution maintenance loop.
%% Once an application is started by zompc this process will wait for a message from
%% the application if that application was written in a way to take advantage of zompc
%% facilities such as post-start upgrade checking.
%%
%% NOTE:
%% Adding clauses to this `receive' is where new functionality belongs.
%% It may make sense to add a `zompc_lib' as an available dependency authors could
%% use to interact with zompc without burying themselves under the complexity that
%% can come with naked send operations. (Would it make sense, for example, to have
%% the registered zompc process convert itself to a gen_server via zompc_lib to
%% provide more advanced functionality?)
exec_wait(State = #s{pid = none, mon = none}) ->
receive
{monitor, Pid} ->
Mon = monitor(process, Pid),
exec_wait(State#s{pid = Pid, mon = Mon});
Unexpected ->
ok = log(warning, "Unexpected message: ~tp", [Unexpected]),
exec_wait(State)
end;
exec_wait(State = #s{pid = Pid, mon = Mon}) ->
receive
{check_update, Requester, Ref} ->
{Response, NewState} = check_update(State),
Requester ! {Ref, Response},
exec_wait(NewState);
{exit, Reason} ->
ok = log(info, "Exiting with: ~tp", [Reason]),
halt(0);
{'DOWN', Mon, process, Pid, normal} ->
ok = log(info, "Application exited normally."),
halt(0);
{'DOWN', Mon, process, Pid, Reason} ->
ok = log(warning, "Application exited with: ~tp", [Reason]),
halt(1);
Unexpected ->
ok = log(warning, "Unexpected message: ~tp", [Unexpected]),
exec_wait(State)
end.
-spec check_update(State) -> {Response, NewState}
when State :: state(),
Response :: term(),
NewState :: state().
%% @private
%% Check for updated version availability of the current application.
%% The return value should probably provide up to three results, a Major, Minor and
%% Patch update, and allow the Requestor to determine what to do with it via some
%% interaction.
check_update(State) ->
ok = log(info, "Would be checking for an update of the current application now..."),
Response = "Nothing was checked, but you can imagine it to have been.",
{Response, State}.