fac(N) when N>0 -> N * fac(N-1); fac(0) -> 1.
Echo = spawn(echo,loop,[]),
Echo ! {self(),"Here is a message"},
....
loop() ->
receive
{From,Msg} -> From ! Msg, loop()
end.
Echo = spawn(SomeNode,echo,loop,[]),
....
-module(bankserver).
-export([start/1]).
start(Sum) ->
register(bank,self()),
account(Sum).
account(Sum) ->
receive
{Pid, Ref, Amount} ->
NewSum = Sum+Amount,
Pid ! {Ref,NewSum},
account(NewSum);
stop -> nil
end.
% spawn a bank account process with initial Sum 1000
Bank_pid = spawn(BankNode,bankserver,start,[1000]),
...
Ref = make_ref(),
Bank_pid ! {self(),Ref,17},
receive
{Ref,New_balance} ->
...
end,
%%% rexec - Erlang remote execution handler
%%% send messages of form: {From, Ref, M, F, A} (sent by call/3 or call/4)
%%% will respond with: From ! {Ref, apply(M, F, A)
-module(rexec).
-export([call/3,call/4,handler/5,server/0,start/0,test/0]).
...
%%% call - send request to rexec server on specified node & show response
call(N, M, F, A) ->
Ref = make_ref(),
{rexec,N} ! {self(), Ref, M, F, A},
wait_resp(Ref).
%%% wait on response (or timeout after 5 secs)
wait_resp(Ref) ->
receive
{Ref, Res} -> Res;
Error -> {error, Error}
after 5000 -> {error, timeout}
end.
...
> rexec:call(Node,erlang,date,[]).
...
%%% start - rexec server on this node
start() ->
Pid = spawn(rexec, server, []),
register(rexec, Pid),
Pid.
%%% server - master server loop listening for next message
server() ->
receive
{From, Ref, M, F, A} ->
io:format("rexec: handling ~w~n", [{From, Ref, M, F, A}]),
spawn(rexec, handler, [From, Ref, M, F, A]),
server();
Error ->
io:format("rexec: ERROR received~w~n", [Error]),
server()
end.
%%% handler -> handle current rexec request
handler(From, Ref, M, F, A) ->
Res = (catch apply(M, F, A)),
From ! {Ref, Res},
Res.
> rexec:start().
%% httpd.erl - a simple HTTPD/0.9 web server in Erlang
-module(httpd).
-export([start/0,start/1,start/2,process/2]).
-import(regexp,[split/2]).
-define(defPort,8888). %% port to use if not given
-define(docRoot,"./htdocs"). %% HTML document root
%% start mini HTTPD/0.9 server, can specify port/docroot if wanted
start() -> start(?defPort,?docRoot).
start(Port) -> start(Port,?docRoot).
start(Port,DocRoot) ->
case gen_tcp:listen(Port, [binary,{packet, 0},{active, false}]) of
{ok, LSock} -> server_loop(LSock,DocRoot);
{error, Reason} -> exit({Port,Reason})
end.
%% main server loop - wait for next connection, spawn child to process it
server_loop(LSock,DocRoot) ->
case gen_tcp:accept(LSock) of
{ok, Sock} ->
spawn(?MODULE,process,[Sock,DocRoot]),
server_loop(LSock,DocRoot);
{error, Reason} ->
exit({accept,Reason})
end.
%% process current connection
process(Sock,DocRoot) ->
Req = do_recv(Sock),
{ok,[Cmd|[Name|[Vers|_]]]} = split(Req,"[ \r\n]"),
FileName = DocRoot ++ Name,
LogReq = Cmd ++ " " ++ Name ++ " " ++ Vers,
Resp = case file:read_file(FileName) of
{ok, Data} ->
io:format("~p ~p ok~n",[LogReq,FileName]),
Data;
{error, Reason} ->
io:format("~p ~p failed ~p~n",[LogReq,FileName,Reason]),
error_response(LogReq,file:format_error(Reason))
end,
do_send(Sock,Resp),
gen_tcp:close(Sock).
%% construct HTML for failure message
error_response(LogReq,Reason) ->
"<html><head><title>Request Failed</title></head><body>\n" ++
"<h1>Request Failed</h1>\n" ++ "Your request to " ++ LogReq ++
" failed due to: " ++ Reason ++ "\n</body></html>\n".
%% send a line of text to the socket
do_send(Sock,Msg) ->
case gen_tcp:send(Sock, Msg) of
ok -> ok;
{error, Reason} -> exit(Reason)
end.
%% receive data from the socket
do_recv(Sock) ->
case gen_tcp:recv(Sock, 0) of
{ok, Bin} -> binary_to_list(Bin);
{error, closed} -> exit(closed);
{error, Reason} -> exit(Reason)
end.
%% monitor - simple application monitor
-module(monitor).
-export([start/3,run/3]).
-define(max,5).
%% spawn of monitor process
start(Module, Function, Args) ->
spawn(?MODULE,run,[Module, Function, Args]).
%% start application being monitored with traps being caught
run(Module, Function, Args) ->
process_flag(trap_exit, true),
Child = spawn_link(Module,Function,Args),
monitor(Child, ?max, Module, Function, Args).
%% wait for something to go wrong, log, restart application
monitor(Child, N, Module, Function, Args) ->
receive
{'EXIT', Child, Why} when N > 0 ->
io:format("~p:~p~p died ~p~n", [Module,Function,Args,Why]),
NewChild = spawn_link(Module,Function,Args),
monitor(NewChild,N-1,Module,Function,Args);
{'EXIT', Child, _} ->
io:format('too many restarts on ~p:~p~p!~n', [Module,Function,Args])
end.