Reputation: 171
I have just started reading the Programming Erlang book. There is very single example that works just file.
If I perform:
> c(afile_server).
> c(afile_client).
> Server = afile_server:start(".").
> client:get_file(Server, "file1").
> client:get_file(Server, "file2").
> client:get_file(Server, "file3").
Everything works just file. The three files content are displayed.
But if I do:
> c(afile_server).
> Server = afile_server:start(".").
> Server ! { self(), { get_file, "file1" } }.
> receive
{ Server, Content }
Content
end.
It works just file. But if I change the file that I am trying to read (after invoking the first time), e.g.
> Server ! { self(), { get_file, "file2" } }.
> receive
{ Server, Content }
Content
end.
The receive blocks and nothing is returned. Could you guys help somehow? I guess, it is a very stupid, mistake! Regards.
Files:
Server:
-module(afile_server).
-export([start/1, loop/1]).
start(Dir) -> spawn(afile_server, loop, [Dir]).
loop(Dir) ->
receive
{Client, list_dir} ->
Client ! {self(), file:list_dir(Dir)};
{Client, {get_file, File}} ->
Full = filename:join(Dir, File),
Client ! {self(), file:read_file(Full)}
end,
loop(Dir).
Client
%% ---
%% Excerpted from "Programming Erlang, Second Edition",
%% published by The Pragmatic Bookshelf.
%% Copyrights apply to this code. It may not be used to create training material,
%% courses, books, articles, and the like. Contact us if you are in doubt.
%% We make no guarantees that this code is fit for any purpose.
%% Visit http://www.pragmaticprogrammer.com/titles/jaerlang2 for more book information.
%%---
-module(afile_client).
-export([ls/1, get_file/2]).
ls(Server) ->
Server ! {self(), list_dir},
receive
{Server, FileList} ->
FileList
end.
get_file(Server, File) ->
Server ! {self(), {get_file, File}},
receive
{Server, Content} ->
Content
end.
Upvotes: 3
Views: 44
Reputation: 222090
That is because you're running this in the shell and reusing the name Content
in the receive
pattern and the 2 files presumably have different content in your filesystem, so the receive
blocks until the process gets a message with the same content. To fix this, you can either use a different name for Content
every time, or explicitly "forget" the variable using f(Content)
.
1> c(afile_server).
{ok,afile_server}
2> Server = afile_server:start(".").
<0.64.0>
3> Server ! { self(), { get_file, "file1" } }.
{<0.57.0>,{get_file,"file1"}}
4> receive {Server, Content} -> Content end.
{ok,<<"file1\n">>}
5> Server ! { self(), { get_file, "file2" } }.
{<0.57.0>,{get_file,"file2"}}
6> receive {Server, Content} -> Content after 1000 -> timeout end.
timeout
7> receive {Server, Content2} -> Content2 end.
{ok,<<"file2\n">>}
8> Server ! { self(), { get_file, "file3" } }.
{<0.57.0>,{get_file,"file3"}}
9> receive {Server, Content} -> Content after 1000 -> timeout end.
timeout
10> f(Content).
ok
11> receive {Server, Content} -> Content after 1000 -> timeout end.
{ok,<<"file3\n">>}
Upvotes: 3