Tutorial: Lightweight Processes

4 Process Communications

4.1 It's a Two Way Street

We've spent some time looking at sending messages to processes manually. Now let's see how processes can send messages to each other. This has the practical implication of being able to report back on something from one process to another process which might have initiated the current action.

For instance, if we could have a function that spawns several lightweight processes, each of which may return data and a status code. If these spawned processes have the calling process' ID, then they can, in turn, send their results back to the caller so that the data and statuses may be reported upon.

4.2 Walk the Talk

To demonstrate this, let's update our print-result function to do this: * pattern match for a process id as well as a message * write message about sending data to another process * actually send that data to the other process

Additionally, let's create a new function that spawns the print-result listener and then sends a message to it.

Save the following as messenger-back.lfe:

(defmodule messenger-back
 (export (print-result 0) (send-message 1)))

(defun print-result ()
  (receive
    ((tuple pid msg)
      (: io format '"Received message: '~s'~n" (list msg))
      (: io format '"Sending message to process ~p ...~n" (list pid))
      (! pid (tuple msg))
      (print-result))))

(defun send-message (calling-pid msg)
  (let ((spawned-pid (spawn 'messenger-back 'print-result ())))
    (! spawned-pid (tuple calling-pid msg))))

With these in place, let's start up our LFE REPL and try it out. First we'll compile our code and then kick things off with our send-message function. Note that this will spawn a listener and send it a message:

> (c '"messenger-back")
#(module messenger-back)
> (: messenger-back send-message '"There was a terrible ghastly silence.")
#(<0.25.0> "There was a terrible ghastly silence.")
Received message: 'There was a terrible ghastly silence.'
Sending message to process <0.25.0> ...
>

Let's take a look at shell's message queue (the quick and dirty way) to see if, in fact, the message was sent to the shell process:

> (: c flush)
Shell got {"There was a terrible ghastly silence."}
ok
>

Sure enough, it was :-)

4.3 Conclusion

Well, that about wraps it up. We may add more information about working with Erlang lightweight processes in LFE, but the material covered so far in this tutorial should give you a solid foundation for exploring the ways in which you can use processes to breathe life into your applications.