echo daemon works well enough
This commit is contained in:
@@ -7,3 +7,15 @@
|
||||
- client connects to server
|
||||
- server writes back "hello"
|
||||
- server closes connection
|
||||
|
||||
- x01-noisy-hello:
|
||||
- was going to be hello world over noise
|
||||
- abandoned
|
||||
|
||||
- `x02-_`:
|
||||
- skipped because the `2` key on my laptop doesn't work
|
||||
|
||||
- x03-echo:
|
||||
- telnet echo server
|
||||
- budget version of zx template "traditional erlang service
|
||||
application"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
% @doc echo server client
|
||||
-module(echoc).
|
||||
|
||||
-export([main/0]).
|
||||
|
||||
main() ->
|
||||
io:format("you can't help people who won't help themselves.~n", []).
|
||||
@@ -1,265 +0,0 @@
|
||||
%% @doc
|
||||
%% super simple telnet echo server daemon
|
||||
%%
|
||||
%% no noise yet
|
||||
%%
|
||||
%% pimps and hos model (from trash talk template):
|
||||
%%
|
||||
%% ```
|
||||
%% t_sup
|
||||
%% |
|
||||
%% t_clients
|
||||
%% |
|
||||
%% +--- t_client_man pimp
|
||||
%% |
|
||||
%% +--- t_client_sup bottom bitch
|
||||
%% |
|
||||
%% +--- <0.1.0> (t_client) ho
|
||||
%% +--- <0.2.0> (t_client) ho
|
||||
%% +--- <0.3.0> (t_client) ho
|
||||
%% '''
|
||||
%%
|
||||
%% each ho:
|
||||
%%
|
||||
%% <ul>
|
||||
%% <li>Takes listen socket as arg</li>
|
||||
%% <li>spawns next ho</li>
|
||||
%% </ul>
|
||||
%%
|
||||
%% ```
|
||||
%% start(ListenSocket) ->
|
||||
%% t_client_sup:start_acceptor(ListenSocket).
|
||||
%%
|
||||
%% start_link(ListenSocket) ->
|
||||
%% proc_lib:start_link(?MODULE, init, [self(), ListenSocket]).
|
||||
%%
|
||||
%% init(Parent, ListenSocket) ->
|
||||
%% ok = io:format("~p Listening.~n", [self()]),
|
||||
%% Debug = sys:debug_options([]),
|
||||
%% ok = proc_lib:init_ack(Parent, {ok, self()}),
|
||||
%% listen(Parent, Debug, ListenSocket).
|
||||
|
||||
|
||||
%%
|
||||
%% listen(Parent, Debug, ListenSocket) ->
|
||||
%% case gen_tcp:accept(ListenSocket) of
|
||||
%% {ok, Socket} ->
|
||||
%% {ok, _} = start(ListenSocket),
|
||||
%% {ok, Peer} = inet:peername(Socket),
|
||||
%% ok = io:format("~p Connection accepted from: ~p~n", [self(), Peer]),
|
||||
%% ok = t_client_man:enroll(),
|
||||
%% State = #s{socket = Socket},
|
||||
%% loop(Parent, Debug, State);
|
||||
%% {error, closed} ->
|
||||
%% ok = io:format("~p Retiring: Listen socket closed.~n", [self()]),
|
||||
%% exit(normal)
|
||||
%% end.
|
||||
%% '''
|
||||
%%
|
||||
%% @end
|
||||
-module(echod).
|
||||
|
||||
-include("./ansi.hrl").
|
||||
-export([main/0]).
|
||||
|
||||
|
||||
%% pimp state
|
||||
-record(ps,
|
||||
{lsock = none :: gen_tcp:socket(),
|
||||
hos = [] :: [{pid(), reference()}],
|
||||
ho_names = init_ho_names() :: [string()]}).
|
||||
|
||||
-type pimp_state() :: #ps{}.
|
||||
|
||||
|
||||
%% ho state
|
||||
-record(hs,
|
||||
{name = none :: string(),
|
||||
daddy = none :: pid(),
|
||||
vagene = none :: gen_tcp:socket()}).
|
||||
|
||||
-type ho_state() :: #hs{}.
|
||||
|
||||
|
||||
|
||||
-spec main() -> no_return().
|
||||
%% @doc
|
||||
%% run the echo server daemon
|
||||
|
||||
main() ->
|
||||
%% show the splash screen nigga
|
||||
ok = splash(),
|
||||
case gen_tcp:listen(6969, [binary, {packet, line}, {active, once}]) of
|
||||
{ok, LSock} ->
|
||||
%% we out here
|
||||
%% we not wuz sockitz nigga
|
||||
%% we **be** sockets
|
||||
%% nigga
|
||||
ok = pimp_logfln("Butters iz in the hizzouse: ~tp", [self()]),
|
||||
pimp_loop(#ps{lsock = LSock});
|
||||
{error, closed} ->
|
||||
%% dont be pimp
|
||||
io:format("PIMP ERROR: ~tp~n", [Error])
|
||||
end.
|
||||
|
||||
|
||||
|
||||
-spec splash() -> ok.
|
||||
%% @private
|
||||
%% show splash screen
|
||||
|
||||
splash() ->
|
||||
SplashStr = """
|
||||
RBX example 2 telnet echo server daemon
|
||||
"one" part of the many-to-one
|
||||
""",
|
||||
io:format("~s~n", [SplashStr]).
|
||||
|
||||
|
||||
|
||||
-spec pimp_loop(PimpState) -> NoReturn when
|
||||
PimpState :: pimp_state(),
|
||||
NoReturn :: no_return().
|
||||
%% @private
|
||||
%% runs in context of main
|
||||
|
||||
pimp_loop(PS = #ps{lsock = LSock, hos = Hos, ho_names = Names}) ->
|
||||
%% blocks until client connects
|
||||
case gen_tcp:accept(LSock) of
|
||||
{ok, ASock} ->
|
||||
{HoName, NewNames} = recycle_ho_names(Names),
|
||||
InitHoState = #hs{name = HoName,
|
||||
daddy = self(),
|
||||
vagene = ASock},
|
||||
SpawnHo = fun() -> do_be_ho(InitHoState) end,
|
||||
NewHo = {_Pid, _Ref} = erlang:spawn_monitor(SpawnHo),
|
||||
NewPimpState = PS#ps{hos = [NewHo | Hos],
|
||||
ho_names = NewNames},
|
||||
pimp_loop(NewPimpState);
|
||||
{echo, From, Data} ->
|
||||
echo_except(From, Data, Hos),
|
||||
pimp_loop(PS);
|
||||
{'DOWN', Ref, process, Pid, Info} ->
|
||||
ok = pimp_logfln("ho down: ~tp; reason: ~tw", [Pid, Info]),
|
||||
NewHos = lists:delete({Pid, Ref}, Hos),
|
||||
NewPS = PS#ps{hos = NewHos},
|
||||
pimp_loop(NewPS);
|
||||
Bad ->
|
||||
pimp_logfln("bad msg: ~tw", [Bad]),
|
||||
pimp_logln("liquidating the hos"),
|
||||
liquidate_hos(Hos),
|
||||
gen_tcp:close(LSock)
|
||||
end.
|
||||
|
||||
liquidate_hos([{HoPid, _HoRef} | Hos]) ->
|
||||
pimp_logfln("liquidating ~tp", [HoPid]),
|
||||
exit(HoPid, kill),
|
||||
liquidate_hos(Hos);
|
||||
liquidate_hos([]) ->
|
||||
pimp_logln("it's done").
|
||||
|
||||
|
||||
% skip if equal
|
||||
echo_except(SrcPid, Data, [{SrcPid, _Ref} | Rest]) ->
|
||||
echo_except(SrcPid, Data, Rest);
|
||||
echo_except(SrcPid, Data, [{Pid, _Ref} | Rest]) ->
|
||||
Pid ! {echo, Data},
|
||||
echo_except(SrcPid, Data, Rest);
|
||||
echo_except(_, _, []) ->
|
||||
ok.
|
||||
|
||||
|
||||
-spec spawn_ho(HoState) ->
|
||||
|
||||
|
||||
-spec do_be_ho(HoState) -> NoReturn when
|
||||
HoState :: ho_state(),
|
||||
NoReturn :: no_return().
|
||||
%% @doc
|
||||
%% ain't no rest for the wicked
|
||||
|
||||
do_be_ho(HS = #hs{name = Name, daddy = Daddy, vagene = ASock}) ->
|
||||
Msg = io:format("HI! I'm ~ts. What's your name?\r\n", [Name]),
|
||||
ok = ho_send(ASock, Msg),
|
||||
receive
|
||||
{tcp, ASock, Data} ->
|
||||
ho_rcvd(Data),
|
||||
Daddy ! {echo, self(), Data},
|
||||
do_be_ho(HS);
|
||||
{echo, Data} ->
|
||||
ho_send(ASock, Data),
|
||||
do_be_ho(HS);
|
||||
{tcp_closed, ASock} ->
|
||||
exit(its_fine)
|
||||
end.
|
||||
|
||||
|
||||
pimp_logfln(MsgStr, Args) ->
|
||||
pimp_logln(io_lib:format(MsgStr, Args)).
|
||||
|
||||
pimp_logln(MsgStr) ->
|
||||
PimpPfx = io_lib:format("pimp ~tp :: ", [self()]),
|
||||
Msg = [?ANSI_BOLD([PimpPfx, MsgStr, "\n"])],
|
||||
ok = io:put_chars(Msg),
|
||||
ok.
|
||||
|
||||
|
||||
ho_rcvd(MsgStr) ->
|
||||
ok = io:format("ho ~tp << ~tw~n", [self(), MsgStr]),
|
||||
ok.
|
||||
|
||||
ho_send(Socket, Msg) ->
|
||||
ok = io:format("ho ~tp >> ~tw~n", [self(), Msg]),
|
||||
ok = gen_tcp:send(Socket, Msg),
|
||||
ok.
|
||||
|
||||
|
||||
init_ho_names() ->
|
||||
["Crystal",
|
||||
"Tiffany",
|
||||
"Amber",
|
||||
"Brandy",
|
||||
"Lola",
|
||||
"Angel",
|
||||
"Ginger",
|
||||
"Candy",
|
||||
"Charity",
|
||||
"Anastasia",
|
||||
"Cherry",
|
||||
"Kitty",
|
||||
"Jade",
|
||||
"Destiny",
|
||||
"Devon",
|
||||
"Chastity",
|
||||
"Raven",
|
||||
"Scarlett",
|
||||
"Bambi",
|
||||
"Star",
|
||||
"Paris",
|
||||
"Dallas",
|
||||
"Diamond",
|
||||
"Skye",
|
||||
"Trinity",
|
||||
"Tawny",
|
||||
"Layla",
|
||||
"Lexie",
|
||||
"Roxy",
|
||||
"Porsche",
|
||||
"Nevaeh",
|
||||
"Ashlynn",
|
||||
"Aspen",
|
||||
"Chyna",
|
||||
"Lexus",
|
||||
"Unique",
|
||||
"Chardonnay",
|
||||
"Houston",
|
||||
"London",
|
||||
"Coco",
|
||||
"Luscious",
|
||||
"Delight",
|
||||
"Capri",
|
||||
"Trixie",
|
||||
"Cinnamon"].
|
||||
|
||||
recycle_ho_names([N | Ns]) ->
|
||||
{N, Ns ++ [N]}.
|
||||
@@ -0,0 +1,20 @@
|
||||
% @doc echo server client
|
||||
-module(echoc).
|
||||
|
||||
-export([main/0]).
|
||||
|
||||
main() ->
|
||||
{ok, Socket} = gen_tcp:connect("localhost", 6969, [binary, {packet, 0}]),
|
||||
loop(Socket).
|
||||
|
||||
|
||||
loop(Socket) ->
|
||||
ok = inet:setopts(Socket, [{active, once}]),
|
||||
receive
|
||||
{tcp, Socket, Bytes} ->
|
||||
ok = io:format("< ~tp~n", [Bytes]),
|
||||
loop(Socket);
|
||||
{tcp_closed, Socket} ->
|
||||
ok = io:format("connection terminated~n", []),
|
||||
exit(normal)
|
||||
end.
|
||||
@@ -0,0 +1,249 @@
|
||||
%% @doc
|
||||
%% super simple telnet echo server daemon
|
||||
%%
|
||||
%% no noise yet
|
||||
%%
|
||||
%% pimps and hos model (from trash talk template):
|
||||
%%
|
||||
%% ```
|
||||
%% t_sup
|
||||
%% |
|
||||
%% t_clients
|
||||
%% |
|
||||
%% +--- t_client_man pimp
|
||||
%% |
|
||||
%% +--- t_client_sup bottom bitch
|
||||
%% |
|
||||
%% +--- <0.1.0> (t_client) ho
|
||||
%% +--- <0.2.0> (t_client) ho
|
||||
%% +--- <0.3.0> (t_client) ho
|
||||
%% '''
|
||||
%%
|
||||
%% each ho:
|
||||
%%
|
||||
%% <ul>
|
||||
%% <li>Takes listen socket as arg</li>
|
||||
%% <li>spawns next ho</li>
|
||||
%% </ul>
|
||||
%%
|
||||
%% ```
|
||||
%% start(ListenSocket) ->
|
||||
%% t_client_sup:start_acceptor(ListenSocket).
|
||||
%%
|
||||
%% start_link(ListenSocket) ->
|
||||
%% proc_lib:start_link(?MODULE, init, [self(), ListenSocket]).
|
||||
%%
|
||||
%% init(Parent, ListenSocket) ->
|
||||
%% ok = io:format("~p Listening.~n", [self()]),
|
||||
%% Debug = sys:debug_options([]),
|
||||
%% ok = proc_lib:init_ack(Parent, {ok, self()}),
|
||||
%% listen(Parent, Debug, ListenSocket).
|
||||
%%
|
||||
%% listen(Parent, Debug, ListenSocket) ->
|
||||
%% case gen_tcp:accept(ListenSocket) of
|
||||
%% {ok, Socket} ->
|
||||
%% {ok, _} = start(ListenSocket),
|
||||
%% {ok, Peer} = inet:peername(Socket),
|
||||
%% ok = io:format("~p Connection accepted from: ~p~n", [self(), Peer]),
|
||||
%% ok = t_client_man:enroll(),
|
||||
%% State = #s{socket = Socket},
|
||||
%% loop(Parent, Debug, State);
|
||||
%% {error, closed} ->
|
||||
%% ok = io:format("~p Retiring: Listen socket closed.~n", [self()]),
|
||||
%% exit(normal)
|
||||
%% end.
|
||||
%% '''
|
||||
%%
|
||||
%% @end
|
||||
-module(echod).
|
||||
|
||||
-include("./ansi.hrl").
|
||||
-export([main/0]).
|
||||
|
||||
|
||||
% ho from pimp pov
|
||||
-record(pho,
|
||||
{pid :: pid(),
|
||||
ref :: reference(),
|
||||
name :: string()}).
|
||||
|
||||
%% pimp state
|
||||
-record(ps,
|
||||
{lsock = none :: gen_tcp:socket(),
|
||||
hos = [] :: [#pho{}],
|
||||
ho_names = init_ho_names() :: [string()]}).
|
||||
|
||||
|
||||
%% ho state
|
||||
-record(hs,
|
||||
{name = none :: string(),
|
||||
daddy = none :: pid(),
|
||||
asock = none :: gen_tcp:socket()}).
|
||||
|
||||
|
||||
main() ->
|
||||
io:format("RBX example 2 telnet echo server daemon~n"
|
||||
"`one' part of the many-to-one relationship~n",
|
||||
[]),
|
||||
p_init().
|
||||
|
||||
|
||||
|
||||
% pimp process startup
|
||||
p_init() ->
|
||||
p_logln("pimp startup (p_init)"),
|
||||
Port = 6969,
|
||||
Opts = [binary, {packet, line}, {active, once}],
|
||||
case gen_tcp:listen(Port, Opts) of
|
||||
{ok, LSock} ->
|
||||
ok = p_logfln("pimp starting: ~tp", [self()]),
|
||||
PS_I = #ps{lsock = LSock},
|
||||
PS_II = p_spawn_ho(PS_I),
|
||||
p_loop(PS_II);
|
||||
{error, closed} ->
|
||||
%% dont be pimp
|
||||
p_logln("listen socket closed")
|
||||
end.
|
||||
|
||||
p_loop(PS = #ps{hos = Hos}) ->
|
||||
receive
|
||||
{ho, _HoPid, taken} ->
|
||||
NewPS = p_spawn_ho(PS),
|
||||
p_loop(NewPS);
|
||||
{ho, HoPid, sent, Data} ->
|
||||
HoName = p_ho_name(HoPid, PS),
|
||||
SendMessage = io_lib:format("~ts :: ~ts\r\n", [HoName, Data]),
|
||||
ok = p_echo_except(HoPid, HoName, SendMessage, Hos),
|
||||
p_loop(PS);
|
||||
Down = {'DOWN', _, _, _, _} ->
|
||||
NewPS = p_ho_down(Down, PS),
|
||||
p_loop(NewPS);
|
||||
Unknown ->
|
||||
ok = p_logfln("unknown message: ~tw", [Unknown]),
|
||||
p_loop(PS)
|
||||
end.
|
||||
|
||||
% given pid of ho, get her name
|
||||
p_ho_name(HoPid, #ps{hos = Hos}) ->
|
||||
case lists:keyfind(HoPid, #pho.pid, Hos) of
|
||||
#pho{name = Name} -> Name;
|
||||
false -> "JaneDoe"
|
||||
end.
|
||||
|
||||
% pimp spawns new ho
|
||||
p_spawn_ho(PS = #ps{lsock = LSock, hos = Hos, ho_names = Names}) ->
|
||||
% new name for ho, initial ho state
|
||||
{N, NewNames} = recycle(Names),
|
||||
InitHS = #hs{name = N, daddy = self()},
|
||||
% spawn the new ho
|
||||
ok = p_logfln("spawning new ho: ~ts", [N]),
|
||||
SpawnHo = fun() -> h_init(LSock, InitHS) end,
|
||||
{HPid, HRef} = erlang:spawn_monitor(SpawnHo),
|
||||
% new ho record from Pimp POV
|
||||
NewHo = #pho{pid = HPid, ref = HRef, name = N},
|
||||
ok = p_logfln("spawned new ho: ~tw", [NewHo]),
|
||||
NewPS = PS#ps{hos = [NewHo | Hos], ho_names = NewNames},
|
||||
NewPS.
|
||||
|
||||
% ho down, remove her from roster
|
||||
p_ho_down({'DOWN', _Ref, process, Pid, Info}, PS = #ps{hos = Hos}) ->
|
||||
ok = p_logfln("ho down: ~tp; reason: ~tw", [Pid, Info]),
|
||||
NewHos = lists:keydelete(Pid, #pho.pid, Hos),
|
||||
NewPS = PS#ps{hos = NewHos},
|
||||
NewPS.
|
||||
|
||||
|
||||
% echo message from one ho to all the rest
|
||||
% skip if equal
|
||||
p_echo_except(SrcPid, SrcName, Data, [#pho{pid = SrcPid} | Rest]) ->
|
||||
p_echo_except(SrcPid, SrcName, Data, Rest);
|
||||
p_echo_except(SrcPid, SrcName, Data, [#pho{pid = DstPid} | Rest]) ->
|
||||
DstPid ! {pimp, send, Data},
|
||||
p_echo_except(SrcPid, SrcName, Data, Rest);
|
||||
p_echo_except(_, _, _, []) ->
|
||||
ok.
|
||||
|
||||
%% runs in ho context
|
||||
h_init(LSock, HS = #hs{name = Name, daddy = Daddy, asock = none}) ->
|
||||
h_logln(Name, "h_init"),
|
||||
% this is key: accept needs to run in ho context, otherwise she
|
||||
% doesn't own the acceptor socket
|
||||
%
|
||||
% blocks until client connects
|
||||
case gen_tcp:accept(LSock) of
|
||||
{ok, ASock} ->
|
||||
h_logln(Name, "taken"),
|
||||
% tell daddy to spawn the next ho
|
||||
Daddy ! {ho, self(), taken},
|
||||
Welcome = io_lib:format("HI! I'm ~ts. What's your name?\r\n",
|
||||
[Name]),
|
||||
ok = h_send(Name, ASock, Welcome),
|
||||
HS_II = HS#hs{asock = ASock},
|
||||
h_loop(HS_II);
|
||||
{error, closed} ->
|
||||
h_logln(Name, "didn't get taken")
|
||||
end.
|
||||
|
||||
|
||||
h_loop(HS = #hs{name = Name, daddy = Daddy, asock = ASock}) ->
|
||||
ok = inet:setopts(ASock, [{active, once}]),
|
||||
receive
|
||||
{tcp, ASock, Data} ->
|
||||
Data_II = string:chomp(Data),
|
||||
ok = h_rcvd(Name, Data_II),
|
||||
Daddy ! {ho, self(), sent, Data_II},
|
||||
h_loop(HS);
|
||||
{pimp, send, Data} ->
|
||||
ok = h_send(Name, ASock, Data),
|
||||
h_loop(HS);
|
||||
{tcp_closed, ASock} ->
|
||||
exit(its_fine);
|
||||
Unknown ->
|
||||
ok = h_logfln(Name, "unknown message: ~tw", [Unknown]),
|
||||
h_loop(HS)
|
||||
end.
|
||||
|
||||
|
||||
% pimp log in bold
|
||||
p_logln(LogStr) ->
|
||||
Msg = io_lib:format("!! Daddy :: ~ts~n", [LogStr]),
|
||||
PimpChars = ?ANSI_BOLD([Msg]),
|
||||
io:put_chars(PimpChars).
|
||||
|
||||
p_logfln(LogStr, Args) ->
|
||||
p_logln(io_lib:format(LogStr, Args)).
|
||||
|
||||
|
||||
% ho log dimmed
|
||||
h_logln(HoName, LogStr) ->
|
||||
FMsg = io_lib:format("!! ~ts :: ~ts~n", [HoName, LogStr]),
|
||||
HoChars = ?ANSI_DIM([FMsg]),
|
||||
io:put_chars(HoChars).
|
||||
|
||||
h_logfln(HoName, MsgStr, Args) ->
|
||||
h_logln(HoName, io_lib:format(MsgStr, Args)).
|
||||
|
||||
% normal: john messages
|
||||
h_rcvd(Name, MsgStr) ->
|
||||
Msg = io_lib:format("<< ~ts :: ~ts~n", [Name, MsgStr]),
|
||||
io:put_chars(Msg).
|
||||
|
||||
h_send(Name, Socket, Msg) ->
|
||||
ok = io:format(">> ~ts :: ~ts~n", [Name, Msg]),
|
||||
gen_tcp:send(Socket, Msg).
|
||||
|
||||
|
||||
init_ho_names() ->
|
||||
["Crystal", "Tiffany", "Amber", "Brandy", "Lola", "Angel",
|
||||
"Ginger", "Candy", "Charity", "Anastasia", "Cherry", "Kitty",
|
||||
"Jade", "Destiny", "Devon", "Chastity", "Raven", "Scarlett",
|
||||
"Bambi", "Star", "Paris", "Dallas", "Diamond", "Skye",
|
||||
"Trinity", "Tawny", "Layla", "Lexie", "Roxy", "Porsche",
|
||||
"Nevaeh", "Ashlynn", "Aspen", "Chyna", "Lexus", "Unique",
|
||||
"Chardonnay", "Houston", "London", "Coco", "Luscious",
|
||||
"Delight", "Capri", "Trixie", "Cinnamon"].
|
||||
|
||||
|
||||
|
||||
recycle([N | Ns]) ->
|
||||
{N, Ns ++ [N]}.
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
Alexander
|
||||
Anthony
|
||||
Asher
|
||||
Beau
|
||||
Benjamin
|
||||
Bennett
|
||||
Caleb
|
||||
Carter
|
||||
Charles
|
||||
Cooper
|
||||
Daniel
|
||||
David
|
||||
Dylan
|
||||
Elias
|
||||
Elijah
|
||||
Ethan
|
||||
Ezekiel
|
||||
Ezra
|
||||
Gabriel
|
||||
Grayson
|
||||
Henry
|
||||
Hudson
|
||||
Isaac
|
||||
Isaiah
|
||||
Jack
|
||||
Jackson
|
||||
Jacob
|
||||
James
|
||||
John
|
||||
Joseph
|
||||
Josiah
|
||||
Julian
|
||||
Leo
|
||||
Levi
|
||||
Liam
|
||||
Logan
|
||||
Luca
|
||||
Lucas
|
||||
Luke
|
||||
Mason
|
||||
Mateo
|
||||
Matthew
|
||||
Maverick
|
||||
Michael
|
||||
Miles
|
||||
Noah
|
||||
Oliver
|
||||
Owen
|
||||
Roman
|
||||
Rowan
|
||||
Samuel
|
||||
Santiago
|
||||
Sebastian
|
||||
Theodore
|
||||
Thiago
|
||||
Thomas
|
||||
Waylon
|
||||
Wesley
|
||||
Weston
|
||||
William
|
||||
Wyatt
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
liquidate_hos([{HoPid, _HoRef} | Hos]) ->
|
||||
p_logfln("liquidating ~tp", [HoPid]),
|
||||
exit(HoPid, kill),
|
||||
liquidate_hos(Hos);
|
||||
liquidate_hos([]) ->
|
||||
p_logln("it's done").
|
||||
|
||||
|
||||
Reference in New Issue
Block a user