Skip to content

Instantly share code, notes, and snippets.

@facundoolano
Last active June 12, 2017 14:03
Show Gist options
  • Save facundoolano/f81f747c7d76eb9df25888d7cca8d477 to your computer and use it in GitHub Desktop.
Save facundoolano/f81f747c7d76eb9df25888d7cca8d477 to your computer and use it in GitHub Desktop.
universal server
-module(server).
-export([start/0]).
-export([become/1]).
-export([shutdown/0]).
-export([request/1]).
-export([ping/1]).
-export([factorial/1]).
-export([sum/1]).
%% Public API
start() -> spawn(fun restarter/0).
become(F) -> whereis(universal_server) ! {become, F}.
request(Arg) ->
whereis(universal_server) ! {self(), Arg},
receive
Response -> Response
after 200 ->
timeout
end.
shutdown() -> whereis(universal_server) ! shutdown.
%% Supervisor
restarter() ->
process_flag(trap_exit, true),
Pid = spawn_link(fun () -> universal_server(fun ping/1) end),
register(universal_server, Pid),
receive
{'EXIT', Pid, normal} -> % not a crash
ok;
{'EXIT', Pid, shutdown} -> % manual termination, not a crash
ok;
{'EXIT', Pid, _} ->
restarter()
end.
% Internal server
universal_server(F) ->
receive
{become, NewF} -> universal_server(NewF);
{From, Arg} -> From ! F(Arg),
universal_server(F);
shutdown -> exit(shutdown)
end.
%% functions to use in become messages
ping(Arg) -> {"Pong!", Arg}.
factorial(0) -> 1;
factorial(N) -> factorial(N, 1).
factorial(1, Acc) -> Acc;
factorial(N, Acc) -> factorial(N - 1, N * Acc).
sum(L) -> lists:sum(L).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment