From 69e009e3e1ad899a4609ff327a08512c86dba374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 22 Jun 2017 19:54:26 +0200 Subject: Add {continue, Term} and handle_continue/2 to gen_server If the gen_server process needs to perform an action immediately after initialization or to break the execution of a callback into multiple steps, it can return {continue, term()} in place of the time-out or hibernation value, which will immediately invoke the handle_continue/2 callback with the given term. This provides a more accessible approach to after initialization compared to proc_lib+enter_loop that is also guaranteed to be safe. It also allows callbacks that need to do lengthy or stateful work to checkpoint the state throughout multiple iterations. This can be useful, for example, when implementing behaviours on top of gen_server. --- lib/stdlib/doc/src/gen_server.xml | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'lib/stdlib/doc/src/gen_server.xml') diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml index 7d137fc772..da74e793e6 100644 --- a/lib/stdlib/doc/src/gen_server.xml +++ b/lib/stdlib/doc/src/gen_server.xml @@ -60,6 +60,8 @@ gen_server:abcast -----> Module:handle_cast/2 - -----> Module:handle_info/2 +- -----> Module:handle_continue/2 + - -----> Module:terminate/2 - -----> Module:code_change/3 @@ -88,6 +90,13 @@ gen_server:abcast -----> Module:handle_cast/2 implies at least two garbage collections (when hibernating and shortly after waking up) and is not something you want to do between each call to a busy server.

+ +

If the gen_server process needs to perform an action + immediately after initialization or to break the execution of a + callback into multiple steps, it can return {continue,Continue} + in place of the time-out or hibernation value, which will immediately + invoke the handle_continue/2 callback.

+ @@ -610,12 +619,15 @@ gen_server:abcast -----> Module:handle_cast/2 State = term() Result = {reply,Reply,NewState} | {reply,Reply,NewState,Timeout}   | {reply,Reply,NewState,hibernate} +   | {reply,Reply,NewState,{continue,Continue}}   | {noreply,NewState} | {noreply,NewState,Timeout}   | {noreply,NewState,hibernate} +   | {noreply,NewState,{continue,Continue}}   | {stop,Reason,Reply,NewState} | {stop,Reason,NewState}  Reply = term()  NewState = term()  Timeout = int()>=0 | infinity +  Continue = term()  Reason = term() @@ -673,9 +685,11 @@ gen_server:abcast -----> Module:handle_cast/2 State = term() Result = {noreply,NewState} | {noreply,NewState,Timeout}   | {noreply,NewState,hibernate} +   | {noreply,NewState,{continue,Continue}}   | {stop,Reason,NewState}  NewState = term()  Timeout = int()>=0 | infinity +  Continue = term()  Reason = term() @@ -689,6 +703,41 @@ gen_server:abcast -----> Module:handle_cast/2 + + Module:handle_continue(Continue, State) -> Result + Handle a continue instruction. + + Continue = term() + State = term() + Result = {noreply,NewState} | {noreply,NewState,Timeout} +   | {noreply,NewState,hibernate} +   | {noreply,NewState,{continue,Continue}} +   | {stop,Reason,NewState} +  NewState = term() +  Timeout = int()>=0 | infinity +  Continue = term() +  Reason = normal | term() + + + +

This callback is optional, so callback modules need to + export it only if they return {continue,Continue} + from another callback. If continue is used and the callback + is not implemented, the process will exit with undef + error.

+
+

This function is called by a gen_server process whenever + a previous callback returns {continue, Continue}. + handle_continue/2 is invoked immediately after the previous + callback, which makes it useful for performing work after + initialization or for splitting the work in a callback in + multiple steps, updating the process state along the way.

+

For a description of the other arguments and possible return values, + see + Module:handle_call/3.

+
+
+ Module:handle_info(Info, State) -> Result Handle an incoming message. @@ -697,6 +746,7 @@ gen_server:abcast -----> Module:handle_cast/2 State = term() Result = {noreply,NewState} | {noreply,NewState,Timeout}   | {noreply,NewState,hibernate} +   | {noreply,NewState,{continue,Continue}}   | {stop,Reason,NewState}  NewState = term()  Timeout = int()>=0 | infinity @@ -726,7 +776,7 @@ gen_server:abcast -----> Module:handle_cast/2 Args = term() Result = {ok,State} | {ok,State,Timeout} | {ok,State,hibernate} -  | {stop,Reason} | ignore +  | {ok,State,{continue,Continue}} | {stop,Reason} | ignore  State = term()  Timeout = int()>=0 | infinity  Reason = term() -- cgit v1.2.3