Skip to content

Instantly share code, notes, and snippets.

@cooldaemon
Created April 7, 2009 16:00
Show Gist options
  • Save cooldaemon/91309 to your computer and use it in GitHub Desktop.
Save cooldaemon/91309 to your computer and use it in GitHub Desktop.
Restore state on supervisor restart.
-module(keep_state).
-author('cooldaemon@gmail.com').
-export([test/0]).
test() ->
keep_state_sup:start_link(),
{} = keep_state_server:get_state(),
keep_state_server:put_state(foo),
foo = keep_state_server:get_state(),
keep_state_server:crash(),
timer:sleep(250),
foo = keep_state_server:get_state(),
keep_state_sup:stop(),
ok.
-module(keep_state_server).
-author('cooldaemon@gmail.com').
-behaviour(gen_server).
%% External API
-export([start_link/0, stop/0]).
-export([get_state/0, put_state/1, crash/0]).
%% gen_server callbacks
-export([
init/1,
handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3
]).
%% External API
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
stop() ->
gen_server:call(?MODULE, stop).
get_state() ->
gen_server:call(?MODULE, get_state).
put_state(NewState) ->
gen_server:cast(?MODULE, {put_state, NewState}).
crash() ->
gen_server:cast(?MODULE, crash).
%% gen_server callbacks
init(_Args) ->
{ok, pick_up_state(ets:lookup(keep_state, state))}.
handle_call(stop, _From, State) ->
{stop, normal, stopped, State};
handle_call(get_state, _From, State) ->
{reply, State, State};
handle_call(_Message, _From, State) ->
{reply, ok, State}.
handle_cast({put_state, NewState}, _State) ->
{noreply, NewState};
handle_cast(crash, State) ->
(fun(X) -> X = 1 end)(0),
{noreply, State};
handle_cast(_Message, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(Reason, State) ->
io:fwrite("Stop ~s (~p):~p~n", [?MODULE, self(), Reason]),
ets:insert(keep_state, {state, State}),
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% Internal Functions
pick_up_state([{state, State}]) -> State;
pick_up_state(_Other) -> {}.
-module(keep_state_sup).
-author('cooldaemon@gmail.com').
-behaviour(supervisor).
%% External exports
-export([start_link/0, stop/0]).
%% supervisor callbacks
-export([init/1]).
%% External exports
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
stop() ->
case whereis(?MODULE) of
Pid when is_pid(Pid) ->
exit(Pid, normal),
ok;
_Other ->
not_started
end.
%% supervisor callbacks
init([]) ->
ets:new(keep_state, [set, public, named_table]),
{ok, {
{one_for_one, 2000, 1},
[
{
keep_state_server,
{keep_state_server, start_link, []},
permanent,
brutal_kill,
worker,
[]
}
]
}}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment