Last active
July 29, 2020 04:15
-
-
Save darcros/829754de837414ec437d7268f6980cc6 to your computer and use it in GitHub Desktop.
Concurrent Programming in Erlang - The University of Kent - chapter 1.5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-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. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'd better add
when erlang:is_number(NumServers)
too 👍