Search code examples
recursionerlangmessage-passingerlang-shellhotswap

What is wrong with my message passing example?


I am attempting to send a message from one process that I spawned to another for an assignment, I feel like I am very close here, but I think my syntax is just a bit off:

-module(assignment6).
-export([start/1, process1/2, process2/0, send_message/2]).

process1(N, Pid) ->

    Message = "This is the original Message",

    if 
        N == 1 ->
            timer:sleep(3000),
            send_message(Pid, Message);

        N > 1 ->
            timer:sleep(3000),
            send_message(Pid, Message),
            process1(N-1, Pid);

        true ->
            io:fwrite("Negative/0, Int/Floating-Point Numbers not allowed")
    end.

process2() ->
    recieve
        Message ->
            io:fwrite(Message),
            io:fwrite("~n");
    end.

send_message(Pid, Message) ->
    Pid ! {Message}.

start(N) ->
    Pid = spawn(assignment6, process2, []),
    spawn(assignment6, process1, [N, Pid]).

The goal of this program is that the Message, will be printed out N times when the function is started, but be delayed enough so that I can hot-swap the wording of the message mid-run. I just can't quite get the Message to process2 for printout.


Solution

  • Four small things:

    • It's spelled receive, not recieve
    • Remove the semicolon in process2. The last clause in a receive expression does not have a terminating semicolon. You can see this in the if expression in process1: the first two clauses end with a semicolon, but the third one does not.
    • In process2, print the message like this:

      io:fwrite("~p~n", [Message])
      

      Since Message is a tuple, not a string, passing it as the first argument to io:fwrite causes a badarg error. Let's ask io:fwrite to format it for us instead.

    • process2 should probably call itself after printing the message. Otherwise, it will receive one message and then exit.

    So now you can run the code, and while it's running you can load a new version of the module with a different message (so called "hot code swapping"). Will that change the message being printed? Why / why not?

    It won't. process1 does a local call to itself, which means that it stays in the old version of the module. Do an external call instead (explicitly specifying the module: assignment6:process1(N-1, Pid)), and it will switch to the new version.