(This post has nothing to do with speech technologies or IVR applications. It’s merely a discussion on an implementation detail I described at the Erlang Montreal meetup and it’s rather technical.)
In my previous post about my talk at the Erlang Montreal meetup, slide 15 briefly outlines how session timeouts are implemented in NuGram Hosted Server. The code is duplicated here:
receive
…
after Timeout ->
db:expire_session(self())
end
This code uses the Erlang receive..after construct to handle timeouts. The construct tries to extract a message from the process mailbox, and waits at most Timeout milliseconds if there are no matching messages (variables start with an uppercase letter in Erlang).
This is great when sessions are represented using plain Erlang processes (I described this technique here). But there is a much better way to achieve the same effect when implementing servers using OTP’s gen_server behaviour. (One of our hard learned lessons is to take time to properly learn OTP, Erlang’s Open Telecommunications Platform, before building a production-grade system. It’s definitely worth the investment. It’s what puts Erlang in a totally different category than most programming languages and systems.)
When implementing a server using gen_server, one has to implement a few callback functions (namely handle_call for synchronous calls, handle_cast for asynchronous ones, and handle_info for other messages). In order to specify request timeouts, values returned by those three functions must provide the optional timeout:
handle_call(Request, From, State) ->
Reply = ...
{ok, Reply, NewState, Timeout};
...
If the server does not receive any message during the next Timeout milliseconds, the timeout message is sent to the process and must be handled by the handle_info function. To stop the process, something like the following can be done:
handle_info(timeout, State) ->
%% Do some clean up
{stop, normal, State};
...
This simply tells the server is to be shut down normally and that its last state is State (a great thing to know when things go wrong).

