I have a process which can take a long time to complete it’s work. I had expected that using handle_continue/2
to break it up into smaller tasks would allow the process to respond to system messages between each loop. however that is not the case.
-module(server).
-export([init/1, handle_cast/2, handle_call/3, handle_continue/2]).
-behaviour(gen_server).
init(_Args) ->
{ok, #{}}.
handle_cast(N, State) ->
erlang:display({?MODULE, ?FUNCTION_NAME, N}),
{noreply, State, {continue, N}}.
handle_call(_, _From, State) ->
{noreply, State}.
handle_continue(0, State) ->
erlang:display({?MODULE, ?FUNCTION_NAME, 0}),
{noreply, State};
handle_continue(N, State) ->
{noreply, State, {continue, N - 1}}.
This will loop, calling handle_continue/2
, N
times. Choosing a large value of N
keeps it busy enough that the sys:get_status/1
call times out.
1> {ok, S} = gen_server:start(server, [], []).
{ok,<0.86.0>}
2> gen_server:cast(S, 1000000000), sys:get_status(S).
{server,handle_cast,1000000000}
** exception exit: {timeout,{sys,get_status,[<0.86.0>]}}
in function sys:send_system_msg/2 (sys.erl, line 754)
3> {server,handle_continue,0}
I am assuming that sys:get_status/1
is representative of system messages, am I wrong?
Should we make it work?