3 4 5 6 7

Event loop

13

Usually when your program has an indefinite lifecycle, you have an event loop at some point. Such a program has some state and handle some events. Whenever an event is occurred, the program handles it and provides a new state based on the event occurred and its arguments.

In Erlang you implement such an event loop with tail recursion and receive statement.

We'll implement a sandboxed world which has a timeline and population counter. Every second our world will evolve updating its day and population counters:

-module(world).
-export([start/0]).

start() ->
    loop(0, 100).

loop(Day, Population) ->
    io:format("Day ~p, Population: ~p~n", [Day, Population]),

    receive
        Message ->
            io:format("Message received: ~s~n", [Message]),
            loop(Day, Population)

        after 1000 ->
            loop(Day + 1, round(Population * 1.2))
    end.

Everything seems easy, right? However the program above isn't quite accurate. You see, the after timeout is reset every time receive statement receives a message. It won't fire every 1000 ms as you may expect. Instead, it fires after 1000 ms since the last message has been received. Let's redesign it so the world could evolve exactly once per 1000 ms. To do that we will use external timer on a different Erlang process:

-module(world).
-export([start/0, loop/2]).

start() ->
    Loop = spawn(world, loop, [0, 100]),
    timeline(Loop).

timeline(Loop) ->
    receive
        after 1000 ->
            Loop ! evolve,
            timeline(Loop)
    end.

loop(Day, Population) ->
    io:format("Day ~p, Population: ~p~n", [Day, Population]),

    receive
        {Message, Sender} ->
            io:format("Message received: ~s~n", [Message]),
            loop(Day, Population);

        evolve ->
            loop(Day + 1, round(Population * 1.2))
    end.

Now one process generates update messages and the other updates the world upon the message arrival.

Rate this post:
Lesson 5
Lesson 7
Share this page:

Learning plan

How you write loops in Erlang and other functional programming languages
What is Erlang process and how to spawn it
How to communicate between Erlang processes with messages
6. Event loop
How to organize top-level event loop in your program
7. Records
How to define your own data types with named fields