%% @private
%%
%% This gen_server monitors the tokio runtime so that its failure can be handled
%% by the supervision tree (for example in the case of a panic). Since this is
%% not expected to happen, the reference to the runtime is stored in a
%% persistent_term for efficiency.
-module(erqwest_runtime).
-behaviour(gen_server).
-export([start_link/0, get/0]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2]).
-record(state, {runtime}).
-define(SERVER, ?MODULE).
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
get() ->
persistent_term:get(?MODULE).
%% gen_server implementation
init([]) ->
process_flag(trap_exit, true),
Runtime = erqwest_nif:start_runtime(self()),
persistent_term:put(?MODULE, Runtime),
{ok, #state{runtime=Runtime}}.
handle_call(_Request, _From, State) ->
{reply, ok, State}.
handle_cast(_Request, State) ->
{noreply, State}.
handle_info(erqwest_runtime_stopped, State) ->
{stop, erqwest_runtime_failure, State#state{runtime=undefined}};
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, #state{runtime=undefined}) ->
ok;
terminate(_Reason, #state{runtime=Runtime}) ->
erqwest_nif:stop_runtime(Runtime),
receive
erqwest_runtime_stopped -> ok
end.