%%% @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}.