Instead of sending server responses back to the router, which could potentially create a bottleneck at the router, I had the router keep count of the available frequencies. When an allocate request passes through the router, the router decreases the server's available count; and when a deallocate request passes through the router, the router increases the server's available count (I didn't address the case where a client tries to deallocate a frequency it doesn't own). I also let the clients, which are running infinite loops, fail after I stop the router/servers.
In my code, a server
is a triple {ServerPid, Freqs, AvailableCount}
. For allocate requests, the router sorts the servers using lists:keysort()
on the third term to get the server with the highest AvailableCount. For deallocate requests, the router finds the server corresponding to the frequency: if no servers correspond to the frequency, then the router sends the client an error message; otherwise the router sends a deallcoate request to the corresponding server.
fs.erl:
%% Based on code from
%% Erlang Programming
%% Francecso Cesarini and Simon Thompson
%% O'Reilly, 2008
%% http://oreilly.com/catalog/9780596518189/
%% http://www.erlangprogramming.org/
%% (c) Francesco Cesarini and Simon Thompson
-module(fs).
-export([start/0,allocate/0,deallocate/1,stop/0]).
-export([server_init/1, router_init/1, router/1]).
-export([test/0, start_router/1]).
-export([client/2, test_init/0, test2/0]).
-export([choose_server/1]).
%%======== TESTS ============
test_init() ->
spawn(fs, test2, []),
testing.
test2() ->
Frequencies = [
[10,11,12,13,14,15], %%The number of sublists in Frequencies
[20,21,22,23,24,25], %%determines the number of servers that will
[30,31,32], %%be started.
[40,41]
],
%%Frequencies = [ [], [] ],
start_router(Frequencies),
timer:sleep(1000), %Make sure the servers start before
%sending them requests.
Clients =
lists:map(fun(ClientArgs) ->
spawn(fs, client, ClientArgs)
end,
[[1,1000],[2,2000],[3,3000],[4,4000]] ), %%[Id,Sleep]
io:format("Clients: ~w~n", [Clients]),
stop().
test() ->
io:format("Client is (~w)~n", [self()]),
Frequencies = [
[10,11,12,13,14,15],
[20,21,22,23,24,25]
],
start_router(Frequencies), %%The number of sublists in Frequencies
%%determines the number of servers that will
%%be started.
loop(14).
loop(0) ->
done_looping;
loop(N) ->
timer:sleep(1000),
io:format("Client (~w) got msg: ~w~n", [self(), allocate()]),
loop(N-1).
%%========== ROUTER ============
start_router(Frequencies) ->
Router = spawn(fs, router_init, [Frequencies]),
io:format("start_router: Router: ~w~n", [Router]),
register(router, Router). %% spawn(fs, router_init, [Frequencies])).
router_init(Frequencies) -> %Frequencies = [ [1,2,3], [10,11] ].
Servers = %% A server is a tuple: {ServerPid, Freqs}
lists:map(fun(Freqs) ->
{
spawn(fs, server_init, [{Freqs, []}] ),
Freqs,
length(Freqs)
} %% => {ServerPid,Freqs}
end,
Frequencies), %% e.g. [ [10,11,12], [20,21,22,23] ]
io:format("router_init: Servers: ~lp~n", [Servers]),
router(Servers). %% [FreshServers, StaleServers] => All the servers start off as 'Fresh'.
router(Servers) ->
receive
{request, Client, allocate}=Request ->
case choose_server(Servers) of
no_frequencies_available ->
Client ! {error, no_frequency},
io:format("router: all frequencies taken~n \t~lp~n client(~w) denied~n",
[Servers, Client]),
router(Servers);
{TargetServerPid, _Freqs, _Available}=TargetServer ->
io:format("router/allocate: TargetServer: ~w~n", [TargetServer]),
TargetServerPid ! Request,
io:format("router: sent allocate request to server (~w) from client (~w)~n",
[TargetServer, Client]),
io:format("router/allocate: Servers ~lp~n", [Servers]),
AdjustedServers = adjust_freq_count(TargetServer, Servers, fun(X) -> X-1 end),
io:format("router/allocate: Adjusted Servers: ~lp~n", [AdjustedServers]),
router(AdjustedServers)
end;
{request, Client, {deallocate,Freq}}=Request ->
case find_server(Freq, Servers) of
false ->
io:format("router: no servers allocated frequency ~w~n", [Freq]),
Client ! {reply, ok},
router(Servers);
{TargetServerPid, _, _}=TargetServer ->
io:format("router/deallocate: TargetServer ~w~n", [TargetServer]),
TargetServerPid ! Request,
io:format("router: sent {deallocate,~w} request to server (~w) from client (~w)~n",
[Freq,TargetServerPid,Client]),
io:format("router/deallocate: Servers ~lp~n", [Servers]),
%%Doesn't handle case where client tries to deallocate a freq it doesn't own:
AdjustedServers = adjust_freq_count(TargetServer, Servers, fun(X) -> X+1 end),
io:format("router/deallocate: Adjusted Servers: ~lp~n", [AdjustedServers]),
router(AdjustedServers)
end;
{request, Client, stop} ->
stop_servers(Servers),
Client ! stopped
end.
choose_server(Servers) ->
SortedServers = lists:keysort(3, Servers),
case lists:last(SortedServers) of
{_ServerPid, _Freqs, 0} -> no_frequencies_available;
Server -> Server
end.
adjust_freq_count(TargetServer, Servers, AdjustmentFun) ->
adjust_freq_count(TargetServer, Servers, AdjustmentFun, []).
adjust_freq_count(_, [], _, Acc) ->
lists:reverse(Acc);
adjust_freq_count(TargetServer, [TargetServer|Servers], AdjustmentFun, Acc)->
{ServerPid,Freqs,Available} = TargetServer,
AdjustedTarget = {ServerPid,Freqs,AdjustmentFun(Available)},
adjust_freq_count(TargetServer, Servers, AdjustmentFun, [AdjustedTarget|Acc]);
adjust_freq_count(TargetServer, [Server|Servers], AdjustmentFun, Acc) ->
adjust_freq_count(TargetServer, Servers, AdjustmentFun, [Server|Acc]).
find_server(_Freq, []) ->
false;
find_server(Freq, [{_, Freqs, _}=Server|Servers]) ->
case lists:member(Freq, Freqs) of
false -> find_server(Freq, Servers);
true -> Server
end.
stop_servers([]) ->
servers_stopped;
stop_servers([ {ServerPid,_, _}=Server | Servers ]) ->
ServerPid ! {request, self(), stop},
receive
{reply, _Reply} -> ok
end,
io:format("router: sent stop message to server ~w~n", [Server]),
stop_servers(Servers).
%%========= CLIENT ==========
client(Id, Sleep) ->
handle_allocate_response(allocate(), Id, Sleep).
handle_allocate_response({ok, Freq}, Id, Sleep) ->
io:format("client~w(~w): got frequency ~w~n",
[Id, self(), Freq]),
timer:sleep(Sleep),
deallocate(Freq),
io:format("client~w(~w): called deallocate(~w)~n",
[Id, self(), Freq]),
client(Id, Sleep);
handle_allocate_response({error, no_frequency}, Id, Sleep) ->
io:format("client~w(~w): no frequencies available~n",
[Id, self()]),
timer:sleep(500), %Wait small amount of time, then retry.
client(Id, Sleep).
%%======== SERVER ================
start() ->
register(fs,
spawn(fs, server_init, [])).
server_init(Freqs) ->
%%Frequencies = {get_frequencies(), []},
server_loop(Freqs).
%% Hard Coded
%get_frequencies() -> [10,11,12,13,14,15].
%% The Main Loop
server_loop(Freqs) ->
receive
{request, Pid, allocate} ->
{NewFreqs, Reply} = allocate(Freqs, Pid),
Pid ! {reply, Reply},
io:format("server(~w): Sent allocate reply to client(~w)~n",[self(),Pid]),
server_loop(NewFreqs);
{request, Pid , {deallocate, Freq}} ->
NewFreqs = deallocate(Freqs, Freq),
Pid ! {reply, ok},
server_loop(NewFreqs);
{request, Pid, stop} ->
Pid ! {reply, stopped};
Other ->
io:format("server(~w): got Other message ~w~n", [self(), Other])
end.
%% Functional interface
allocate() ->
router ! {request, self(), allocate},
receive
{reply, Reply} -> Reply
end.
deallocate(Freq) ->
router ! {request, self(), {deallocate, Freq}},
receive
{reply, Reply} -> Reply
end.
stop() ->
router ! {request, self(), stop},
receive
{reply, Reply} -> Reply
end.
%% The Internal Help Functions used to allocate and
%% deallocate frequencies.
allocate({[], Allocated}, _Pid) ->
{{[], Allocated}, {error, no_frequency}};
allocate({[Freq|Free], Allocated}, Pid) ->
{{Free, [{Freq, Pid}|Allocated]}, {ok, Freq}}.
deallocate({Free, Allocated}, Freq) ->
NewAllocated=lists:keydelete(Freq, 1, Allocated),
{[Freq|Free], NewAllocated}.
In the shell:
$ ./run.sh
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V6.4 (abort with ^G)
1> start_router: Router: <0.35.0>
router_init: Servers: [{<0.36.0>,[10,11,12,13,14,15],6},
{<0.37.0>,[20,21,22,23,24,25],6},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
Clients: [<0.40.0>,<0.41.0>,<0.42.0>,<0.43.0>]
router/allocate: TargetServer: {<0.37.0>,[20,21,22,23,24,25],6}
router: sent allocate request to server ({<0.37.0>,[20,21,22,23,24,25],6}) from client (<0.40.0>)
server(<0.37.0>): Sent allocate reply to client(<0.40.0>)
client1(<0.40.0>): got frequency 20
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],6},
{<0.37.0>,[20,21,22,23,24,25],6},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],6},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.36.0>,[10,11,12,13,14,15],6}
router: sent allocate request to server ({<0.36.0>,[10,11,12,13,14,15],6}) from client (<0.41.0>)
server(<0.36.0>): Sent allocate reply to client(<0.41.0>)
client2(<0.41.0>): got frequency 10
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],6},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.37.0>,[20,21,22,23,24,25],5}
router: sent allocate request to server ({<0.37.0>,[20,21,22,23,24,25],5}) from client (<0.42.0>)
server(<0.37.0>): Sent allocate reply to client(<0.42.0>)
client3(<0.42.0>): got frequency 21
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.36.0>,[10,11,12,13,14,15],5}
router: sent allocate request to server ({<0.36.0>,[10,11,12,13,14,15],5}) from client (<0.43.0>)
server(<0.36.0>): Sent allocate reply to client(<0.43.0>)
client4(<0.43.0>): got frequency 11
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: TargetServer {<0.37.0>,[20,21,22,23,24,25],4}
router: sent {deallocate,20} request to server (<0.37.0>) from client (<0.40.0>)
client1(<0.40.0>): called deallocate(20)
router/deallocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.37.0>,[20,21,22,23,24,25],5}
router: sent allocate request to server ({<0.37.0>,[20,21,22,23,24,25],5}) from client (<0.40.0>)
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
server(<0.37.0>): Sent allocate reply to client(<0.40.0>)
client1(<0.40.0>): got frequency 20
router/deallocate: TargetServer {<0.36.0>,[10,11,12,13,14,15],4}
router: sent {deallocate,10} request to server (<0.36.0>) from client (<0.41.0>)
client2(<0.41.0>): called deallocate(10)
router/deallocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.36.0>,[10,11,12,13,14,15],5}
router: sent allocate request to server ({<0.36.0>,[10,11,12,13,14,15],5}) from client (<0.41.0>)
server(<0.36.0>): Sent allocate reply to client(<0.41.0>)
client2(<0.41.0>): got frequency 10
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: TargetServer {<0.37.0>,[20,21,22,23,24,25],4}
router: sent {deallocate,20} request to server (<0.37.0>) from client (<0.40.0>)
client1(<0.40.0>): called deallocate(20)
router/deallocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.37.0>,[20,21,22,23,24,25],5}
router: sent allocate request to server ({<0.37.0>,[20,21,22,23,24,25],5}) from client (<0.40.0>)
server(<0.37.0>): Sent allocate reply to client(<0.40.0>)
client1(<0.40.0>): got frequency 20
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: TargetServer {<0.37.0>,[20,21,22,23,24,25],4}
router: sent {deallocate,21} request to server (<0.37.0>) from client (<0.42.0>)
client3(<0.42.0>): called deallocate(21)
router/deallocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.37.0>,[20,21,22,23,24,25],5}
router: sent allocate request to server ({<0.37.0>,[20,21,22,23,24,25],5}) from client (<0.42.0>)
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
server(<0.37.0>): Sent allocate reply to client(<0.42.0>)
client3(<0.42.0>): got frequency 21
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: TargetServer {<0.37.0>,[20,21,22,23,24,25],4}
router: sent {deallocate,20} request to server (<0.37.0>) from client (<0.40.0>)
router/deallocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
client1(<0.40.0>): called deallocate(20)
router/deallocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.37.0>,[20,21,22,23,24,25],5}
router: sent allocate request to server ({<0.37.0>,[20,21,22,23,24,25],5}) from client (<0.40.0>)
server(<0.37.0>): Sent allocate reply to client(<0.40.0>)
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
client1(<0.40.0>): got frequency 20
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: TargetServer {<0.36.0>,[10,11,12,13,14,15],4}
router: sent {deallocate,11} request to server (<0.36.0>) from client (<0.43.0>)
client4(<0.43.0>): called deallocate(11)
router/deallocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: TargetServer {<0.36.0>,[10,11,12,13,14,15],5}
router: sent {deallocate,10} request to server (<0.36.0>) from client (<0.41.0>)
client2(<0.41.0>): called deallocate(10)
router/deallocate: Servers [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],6},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.36.0>,[10,11,12,13,14,15],6}
router: sent allocate request to server ({<0.36.0>,[10,11,12,13,14,15],6}) from client (<0.43.0>)
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],6},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
server(<0.36.0>): Sent allocate reply to client(<0.43.0>)
router/allocate: TargetServer: {<0.36.0>,[10,11,12,13,14,15],5}
client4(<0.43.0>): got frequency 10
router: sent allocate request to server ({<0.36.0>,[10,11,12,13,14,15],5}) from client (<0.41.0>)
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],5},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
server(<0.36.0>): Sent allocate reply to client(<0.41.0>)
client2(<0.41.0>): got frequency 11
router/deallocate: TargetServer {<0.37.0>,[20,21,22,23,24,25],4}
router: sent {deallocate,20} request to server (<0.37.0>) from client (<0.40.0>)
client1(<0.40.0>): called deallocate(20)
router/deallocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/deallocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: TargetServer: {<0.37.0>,[20,21,22,23,24,25],5}
router: sent allocate request to server ({<0.37.0>,[20,21,22,23,24,25],5}) from client (<0.40.0>)
server(<0.37.0>): Sent allocate reply to client(<0.40.0>)
router/allocate: Servers [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],5},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
router/allocate: Adjusted Servers: [{<0.36.0>,[10,11,12,13,14,15],4},
{<0.37.0>,[20,21,22,23,24,25],4},
{<0.38.0>,[30,31,32],3},
{<0.39.0>,[40,41],2}]
client1(<0.40.0>): got frequency 20
router: stop request: Client is: <0.34.0>
router: sent stop message to server {<0.36.0>,[10,11,12,13,14,15],4}
router: sent stop message to server {<0.37.0>,[20,21,22,23,24,25],4}
router: sent stop message to server {<0.38.0>,[30,31,32],3}
router: sent stop message to server {<0.39.0>,[40,41],2}
=ERROR REPORT==== 2-May-2017::16:15:38 ===
Error in process <0.40.0> with exit value: {badarg,[{fs,deallocate,1,[{file,"fs.erl"},{line,230}]},{fs,handle_allocate_response,3,[{file,"fs.erl"},{line,176}]}]}
=ERROR REPORT==== 2-May-2017::16:15:39 ===
Error in process <0.41.0> with exit value: {badarg,[{fs,deallocate,1,[{file,"fs.erl"},{line,230}]},{fs,handle_allocate_response,3,[{file,"fs.erl"},{line,176}]}]}
=ERROR REPORT==== 2-May-2017::16:15:39 ===
Error in process <0.42.0> with exit value: {badarg,[{fs,deallocate,1,[{file,"fs.erl"},{line,230}]},{fs,handle_allocate_response,3,[{file,"fs.erl"},{line,176}]}]}
=ERROR REPORT==== 2-May-2017::16:15:41 ===
Error in process <0.43.0> with exit value: {badarg,[{fs,deallocate,1,[{file,"fs.erl"},{line,230}]},{fs,handle_allocate_response,3,[{file,"fs.erl"},{line,176}]}]}
i().
Pid Initial Call Heap Reds Msgs
Registered Current Function Stack
<0.0.0> otp_ring0:start/2 1598 3249 0
init init:loop/1 2
<0.3.0> erlang:apply/2 6772 141890 0
erl_prim_loader erl_prim_loader:loop/3 6
<0.6.0> gen_event:init_it/6 2586 2656 0
error_logger gen_event:fetch_msg/5 8
<0.7.0> erlang:apply/2 1598 470 0
application_controlle gen_server:loop/6 7
<0.9.0> application_master:init/4 376 44 0
application_master:main_loop/2 6
<0.10.0> application_master:start_it/4 233 69 0
application_master:loop_it/4 5
<0.11.0> supervisor:kernel/1 2586 45786 0
kernel_sup gen_server:loop/6 9
<0.12.0> rpc:init/1 233 35 0
rex gen_server:loop/6 9
<0.13.0> global:init/1 233 52 0
global_name_server gen_server:loop/6 9
<0.14.0> erlang:apply/2 233 19 0
global:loop_the_locker/1 5
<0.15.0> erlang:apply/2 233 3 0
global:loop_the_registrar/0 2
<0.16.0> inet_db:init/1 233 251 0
inet_db gen_server:loop/6 9
<0.17.0> global_group:init/1 233 59 0
global_group gen_server:loop/6 9
<0.18.0> file_server:init/1 233 92 0
file_server_2 gen_server:loop/6 9
<0.19.0> erlang:apply/2 1598 93480 0
code_server code_server:loop/1 3
<0.20.0> supervisor_bridge:standard_error/ 233 41 0
standard_error_sup gen_server:loop/6 9
<0.21.0> erlang:apply/2 233 9 0
standard_error standard_error:server_loop/1 2
<0.22.0> supervisor_bridge:user_sup/1 233 60 0
gen_server:loop/6 9
<0.23.0> user_drv:server/2 1598 4754 0
user_drv user_drv:server_loop/5 8
<0.24.0> group:server/3 2586 43050 0
user group:server_loop/3 4
<0.25.0> group:server/3 1598 11247 0
group:server_loop/3 4
<0.26.0> erlang:apply/2 17731 3764 0
shell:shell_rep/4 17
<0.27.0> kernel_config:init/1 233 286 0
gen_server:loop/6 9
<0.28.0> supervisor:kernel/1 233 58 0
kernel_safe_sup gen_server:loop/6 9
<0.32.0> erlang:apply/2 1598 18232 0
c:pinfo/1 50
Total 45254 369656 0
219
ok
2>