Skip to content

Instantly share code, notes, and snippets.

@darcros
Last active July 29, 2020 04:15
Show Gist options
  • Save darcros/829754de837414ec437d7268f6980cc6 to your computer and use it in GitHub Desktop.
Save darcros/829754de837414ec437d7268f6980cc6 to your computer and use it in GitHub Desktop.
Concurrent Programming in Erlang - The University of Kent - chapter 1.5
-module(palindrome).
-export([server/0, client/2, start_load_balancer/1, test_all/0]).
rem_punct(String) ->
lists:filter(fun (Ch) ->
not lists:member(Ch, "\"'\t\n ")
end,
String).
to_small(String) ->
lists:map(fun (Ch) ->
case $A =< Ch andalso Ch =< $Z of
true -> Ch + 32;
false -> Ch
end
end,
String).
palindrome_check(String) ->
Normalise = to_small(rem_punct(String)),
lists:reverse(Normalise) == Normalise.
server() ->
receive
{check, ClientPid, String} ->
io:format("[server ~p] checking palindrome \"~s\"~n", [self(), String]),
case palindrome_check(String) of
true -> ClientPid ! {result, String ++ " is a palindrome"};
false -> ClientPid ! {result, String ++ " isn't a palindrome"}
end,
server();
_ ->
io:format("[server ~p] terminating~n", [self()]),
ok
end.
client(ServerPid, Words) ->
lists:foreach(fun (Word) ->
io:format("[client ~p] sending word \"~s\" to ~p~n", [self(), Word, ServerPid]),
ServerPid ! {check, self(), Word},
receive
{result, Result} ->
io:format("[client ~p] received result: \"~s\"~n", [self(), Result])
end
end,
Words).
start_load_balancer(NumServers) when erlang:is_number(NumServers) ->
Servers = lists:map(fun (_) ->
spawn(palindrome, server, [])
end,
lists:seq(0, NumServers)),
load_balancer(Servers).
load_balancer(Servers) ->
receive
{check, ClientPid, String} ->
[Server | Rest] = Servers,
Server ! {check, ClientPid, String},
io:format("[Load balancer ~p] forwarding to server ~p~n", [self(), Server]),
load_balancer(Rest ++ [Server]);
_ ->
io:format("[Load balancer ~p] received unknown message, sending stop to all servers~n", [self()]),
lists:foreach(fun (Server) ->
Server ! stop
end,
Servers),
ok
end.
test_all() ->
LoadBalancer = spawn(palindrome, start_load_balancer, [3]),
spawn(palindrome, client, [LoadBalancer, ["bob", "alice", "racecar"]]),
spawn(palindrome, client, [LoadBalancer, ["My gym", "Was it a cat I saw?", "foo", "bar"]]),
timer:sleep(500),
io:format("seding stop message~n"),
LoadBalancer ! stop.
@naufraghi
Copy link

I'd better add when erlang:is_number(NumServers) too 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment