Programming Erlang, 2 e., Chapter 2, Exercise 4, put_file()

Yao Bao free7by@REDACTED
Sat Jan 1 03:54:35 CET 2022


Hello,

> Now that we have figured out the bug -- the shell sent a command to the server for which there was no matching receive pattern -- it begs the question: how do I detect when a process is sent a message for which there is no matching receive pattern?

Perhaps we cannot put any guarantee on this.

>    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)};
> 	{Client, {put_file, File, Bytes}} ->
> 	    Full = filename:join(Dir, File),
> 	    Client ! {self(), file:write_file(Full, Bytes)};
> 	{Client, U} ->
> 	    Client ! {self(), {error, "Unknown command", U}};
> 	{Client, U, A} ->
> 	    Client ! {self(), {error, "Unknown command", U, A}};
> 	{Client, U, A, B} ->
> 	    Client ! {self(), {error, "Unknown command", U, A, B}}
>    end,

We cannot enumerate all kinds of patterns in the limited receive expression,
but we can solve this problem via properly designed message pattern.

For the receiver, we can say, it can receive one kinds of message,
which is: {Client, Command}, then the sender should send messages matching
this pattern, or, the server has no responsibility for replying anything.

With this design, the receive expression can be written as:

>    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)};
> 	{Client, {put_file, File, Bytes}} ->
> 	    Full = filename:join(Dir, File),
> 	    Client ! {self(), file:write_file(Full, Bytes)};
> 	{Client, Command} ->
> 	    Client ! {self(), {error, "Unknown command", Command}}
>    end,

The sender can send such messages:

> Server ! {self(), foo}

> Server ! {self(), {foo, bar}}.
> Server ! {self(), {foo, bar, baz}}.

After sending, the sender say:

    receive C -> C end

And pattern C can match those messages happily.

By the way, in my understanding, in the worst case, message passing
is reliable but no guarantee, so the receiver might consider that worst case and
handle it properly (add timeout mechanism is an example).

Cheers,
Yao



More information about the erlang-questions mailing list