Я вижу, что у вас есть две основные проблемы в процессе сервера:
- Отправка сообщения с сервера работнику базы данных.
- Отправка сообщения, полученного сервером от воркера, обратно клиенту.
Отправка сообщения исполнителю
Ваши следующие строки кода от L8 до L10 неверны.
%% ...
Worker = spawn(server, getNameFromDataBase(self()), []),
Worker ! Name,
From ! LastName,
%% ...
Чтобы создать функцию как процесс, вы должны предоставить любой аргумент(ы) функции как члены списка в третьем аргументе spawn/3
, а не вызывать функцию напрямую.
Worker = spawn(server, getNameFromDataBase, [self()]),
Отправка только Name
Worker
останется незамеченной, так как getNameFromDataBase
ожидает {name, Name}
. Это должно быть изменено на
Worker ! {name, Name}
Отправка результата (фамилия) клиенту
Нет смысла отправлять From ! LastName
на L10, так как вы не получили LastName
. Это должно быть перемещено во второе выражение соответствия, когда сервер получил {database, LastName}
от работника. Кроме того, client
ожидает {server, LastName}
, а не LastName
. Так что должно было быть From ! {server, LastName}
.
Однако есть проблема. Вы не можете получить доступ к From
в этой области, потому что она никогда не была определена.
%% ...
{database, LastName} ->
From ! {server, LastName}, % `From` is not defined
server()
%% ...
Что вы можете сделать, не изменяя кортеж сообщения, так это определить другую функцию server/1
, например:
server(ClientPID) ->
receive
{_, LastName} ->
ClientPID ! {server, LastName},
server()
end.
и вызовите это из server/0
:
server() ->
receive
{From, {client, Name}} ->
io:format("Server has received request for ~p from ~p~n", [Name, From]),
Worker = spawn(?MODULE, getNameFromDataBase, [self()]),
Worker ! {name, Name},
server(From) % call `server/1` with the client's PID
end.
Наконец, чтобы завершить все, если вы еще этого не сделали, создайте инициирующую функцию для порождения процессов server
и client
. Вот завершенный код:
server() ->
receive
{From, {client, Name}} ->
io:format("Server has received request for ~p from ~p~n", [Name, From]),
Worker = spawn(?MODULE, getNameFromDataBase, [self()]),
Worker ! {name, Name},
server(From)
end.
server(ClientPID) ->
receive
{_, LastName} ->
ClientPID ! {server, LastName},
server()
end.
getNameFromDataBase(ServerAddr) ->
receive
{name, Name} ->
io:format("worker received ~p~n",[Name]),
timer:sleep(5000),
ServerAddr ! {database, "Johnson"}
end.
client(ServerPID) ->
ServerPID ! {self(),{client, "Jim"}},
receive
{server, LastName} ->
io:format("Client got person's last name ~p from Server ~n", [LastName])
end.
run() ->
ServerPID = spawn(?MODULE, server, []),
spawn(?MODULE, client, [ServerPID]).
Последний совет: не используйте параметр компиляции export_all
. Экспортируйте только необходимые функции для хорошей инкапсуляции.
person
Pie 'Oh' Pah
schedule
05.04.2018