Quick look at new :gen_server handle_continue callback
19 June 2018. Erlang OTP 21.0 has been released today and I’m going to
describe how new :gen_server handle_continue
callback works.
Setup
Erlang 21.0
and Elixir 1.6.6-otp-21
installed using asdf version manager
Let’s write something basic
Initial state of our GenServer is 0 and it implements single handle_info
that
increments state by 1 and logs new value.
Inside init callback we are sending three :inc_and_log
messages to
GenServer itself and logging additional message, so when we start it we can
see following logs:
Nothing special so far.
Continue
Let’s modify handle_info
return value and add new handle_continue
callback.
When we start our GenServer now, we can see different values in logs:
The reason for this is that when any callback returns {:continue, term}
then
handle_continue
is invoked immediately. In other words after every
handle_info
there was handle_continue
which incremented state value one more time.
More realistic use case
Let’s imagine call
that returns current state and calculates new one.
Process invoking call doesn’t need to know new state, but it’s blocked until calculation ends.
It also can’t be solved by moving calculation to handle_info
callback because
it can’t be guaranteed that there are no other messages waiting for being processed.
It’s a kind of situation where handle_continue
is very convenient:
Last thing
There's no support for handle_continue
in elixir yet. It means that @impl true
before handle_continue
will result in compilation warning.
(EDIT: this is no longer true for Elixir v1.7
)