Generic server behavior.
This behavior module provides the server of a client-server
relation. A generic server process (gen_server) implemented using
this module has a standard set of interface functions and
includes functionality for tracing and error reporting. It also
fits into an OTP supervision tree. For more information, see section
gen_server Behaviour in OTP Design Principles.
A gen_server process assumes all specific parts to be located in
a callback module exporting a predefined set of functions.
The relationship between the behavior functions and the callback
functions is as follows:
gen_server module Callback module ----------------- --------------- gen_server:start gen_server:start_link -----> Module:init/1 gen_server:stop -----> Module:terminate/2 gen_server:call gen_server:multi_call -----> Module:handle_call/3 gen_server:cast gen_server:abcast -----> Module:handle_cast/2 - -----> Module:handle_info/2 - -----> Module:handle_continue/2 - -----> Module:terminate/2 - -----> Module:code_change/3
If a callback function fails or returns a bad value, the
gen_server process terminates.
A gen_server process handles system messages as described in
sys(3). The sys module
can be used for debugging a gen_server process.
Notice that a gen_server process does not trap exit signals
automatically, this must be explicitly initiated in the callback
module.
Unless otherwise stated, all functions in this module fail if
the specified gen_server process does not exist or if bad
arguments are specified.
The gen_server process can go into hibernation
(see
erlang:hibernate/3) if a callback
function specifies 'hibernate' instead of a time-out value. This
can be useful if the server is expected to be idle for a long
time. However, use this feature with care, as hibernation
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.
Functions
Nodes = [Node]�Node = atom()Name = atom()Request = term()
Sends an asynchronous request to the gen_server processes
locally registered as Name at the specified nodes. The function
returns immediately and ignores nodes that do not exist, or
where the gen_server Name does not exist.
The gen_server processes call
Module:handle_cast/2 to handle the request.
For a description of the arguments, see
multi_call/2,3,4.
ServerRef = Name | {Name,Node} | {global,GlobalName}��| {via,Module,ViaName} | pid()�Node = atom()�GlobalName = ViaName = term()Request = term()Timeout = int()>0 | infinityReply = term()
Makes a synchronous call to the ServerRef of the
gen_server process
by sending a request and waiting until a reply arrives or a
time-out occurs. The gen_server process calls
Module:handle_call/3 to handle the request.
ServerRef can be any of the following:
- The pid
Name, if thegen_serverprocess is locally registered{Name,Node}, if thegen_serverprocess is locally registered at another node{global,GlobalName}, if thegen_serverprocess is globally registered{via,Module,ViaName}, if thegen_serverprocess is registered through an alternative process registry
Request is any term that is passed as one of
the arguments to Module:handle_call/3.
Timeout is an integer greater than zero that
specifies how many milliseconds to wait for a reply, or
the atom infinity to wait indefinitely. Defaults to
5000. If no reply is received within the specified time,
the function call fails. If the caller catches the failure
and continues running, and the server is just late with the reply,
it can arrive at any time later into the message queue of the caller.
The caller must in this case be prepared for this
and discard any such garbage messages that are two element
tuples with a reference as the first element.
The return value Reply is defined in the return value
of Module:handle_call/3.
The call can fail for many reasons, including time-out and the
called gen_server process dying before or during the call.
ServerRef = Name | {Name,Node} | {global,GlobalName}��| {via,Module,ViaName} | pid()�Node = atom()�GlobalName = ViaName = term()Request = term()
Sends an asynchronous request to the ServerRef of the
gen_server process
and returns ok immediately, ignoring
if the destination node or gen_server process does not exist.
The gen_server process calls
Module:handle_cast/2 to handle the request.
For a description of ServerRef, see
call/2,3.
Request is any term that is passed as one
of the arguments to Module:handle_cast/2.
Module = atom()Options = [Option]�Option = {debug,Dbgs} | {hibernate_after,HibernateAfterTimeout}��Dbgs = [Dbg]���Dbg = trace | log | statistics����| {log_to_file,FileName} | {install,{Func,FuncState}}State = term()ServerName = {local,Name} | {global,GlobalName}��| {via,Module,ViaName}�Name = atom()�GlobalName = ViaName = term()Timeout = int() | infinity
Makes an existing process into a gen_server process. Does not
return, instead the calling process enters the gen_server
process receive
loop and becomes a gen_server process. The process
must have been started using one of the start functions in
proc_lib(3). The user is
responsible for any initialization of the process, including
registering a name for it.
This function is useful when a more complex initialization procedure
is needed than the gen_server process behavior provides.
Module, Options, and ServerName have
the same meanings as when calling
start[_link]/3,4.
However, if ServerName is specified, the process must
have been registered accordingly before this function
is called.
State and Timeout have the same meanings as in
the return value of
Module:init/1.
The callback module Module does not need to
export an init/1 function.
The function fails if the calling process was not started by a
proc_lib start function, or if it is not registered
according to ServerName.
Nodes = [Node]�Node = atom()Name = atom()Request = term()Timeout = int()>=0 | infinityResult = {Replies,BadNodes}�Replies = [{Node,Reply}]��Reply = term()BadNodes = [Node]
Makes a synchronous call to all gen_server processes locally
registered as Name at the specified nodes by first
sending a request to every node and then waits for
the replies. The gen_server process calls
Module:handle_call/3 to handle the request.
The function returns a tuple {Replies,BadNodes}, where
Replies is a list of {Node,Reply} and
BadNodes is a list of node that either did not exist,
or where the gen_server Name did not exist or did not
reply.
Nodes is a list of node names to which the request
is to be sent. Default value is the list of all known nodes
[node()|nodes()].
Name is the locally registered name of each
gen_server process.
Request is any term that is passed as one of
the arguments to Module:handle_call/3.
Timeout is an integer greater than zero that
specifies how many milliseconds to wait for each reply, or
the atom infinity to wait indefinitely. Defaults
to infinity. If no reply is received from a node within
the specified time, the node is added to BadNodes.
When a reply Reply is received from the gen_server
process at a node Node, {Node,Reply} is added to
Replies. Reply is defined in the return value of
Module:handle_call/3.
Warning!
If one of the nodes cannot process monitors, for example,
C or Java nodes, and the gen_server process is not started
when the requests are sent, but starts within 2 seconds,
this function waits the whole Timeout,
which may be infinity.
This problem does not exist if all nodes are Erlang nodes.
To prevent late answers (after the time-out) from polluting the message queue of the caller, a middleman process is used to do the calls. Late answers are then discarded when they arrive to a terminated process.
Client - see belowReply = term()Result = term()
This function can be used by a gen_server process to
explicitly send a reply to a client that called
call/2,3 or
multi_call/2,3,4,
when the reply cannot be defined in the return value of
Module:handle_call/3.
Client must be the From argument provided to
the callback function. Reply is any term
given back to the client as the return value of
call/2,3 or multi_call/2,3,4.
The return value Result is not further defined, and
is always to be ignored.
ServerName = {local,Name} | {global,GlobalName}��| {via,Module,ViaName}�Name = atom()�GlobalName = ViaName = term()Module = atom()Args = term()Options = [Option]�Option = {debug,Dbgs} | {timeout,Time} | {hibernate_after,HibernateAfterTimeout} | {spawn_opt,SOpts}��Dbgs = [Dbg]���Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}��SOpts = [term()]Result = {ok,Pid} | ignore | {error,Error}�Pid = pid()�Error = {already_started,Pid} | term()
Creates a standalone gen_server process, that is, a
gen_server process that is not part of a supervision tree
and thus has no supervisor.
For a description of arguments and return values, see
start_link/3,4.
ServerName = {local,Name} | {global,GlobalName}��| {via,Module,ViaName}�Name = atom()�GlobalName = ViaName = term()Module = atom()Args = term()Options = [Option]�Option = {debug,Dbgs} | {timeout,Time} | {hibernate_after,HibernateAfterTimeout} | {spawn_opt,SOpts}��Dbgs = [Dbg]���Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}��SOpts = [term()]Result = {ok,Pid} | ignore | {error,Error}�Pid = pid()�Error = {already_started,Pid} | term()
Creates a gen_server process as part of a supervision tree.
This function is to be called, directly or indirectly, by
the supervisor. For example, it ensures that
the gen_server process is linked to the supervisor.
The gen_server process calls
Module:init/1 to
initialize. To ensure a synchronized startup procedure,
start_link/3,4 does not return until
Module:init/1 has returned.
-
If
ServerName={local,Name}, thegen_serverprocess is registered locally asNameusingregister/2. -
If
ServerName={global,GlobalName}, thegen_serverprocess id registered globally asGlobalNameusingglobal:register_name/2If no name is provided, thegen_serverprocess is not registered. -
If
ServerName={via,Module,ViaName}, thegen_serverprocess registers with the registry represented byModule. TheModulecallback is to export the functionsregister_name/2,unregister_name/1,whereis_name/1, andsend/2, which are to behave like the corresponding functions inglobal. Thus,{via,global,GlobalName}is a valid reference.
Module is the name of the callback module.
Args is any term that is passed as
the argument to
Module:init/1.
-
If option
{timeout,Time}is present, thegen_serverprocess is allowed to spendTimemilliseconds initializing or it is terminated and the start function returns{error,timeout}. -
If option
{hibernate_after,HibernateAfterTimeout}is present, thegen_serverprocess awaits any message forHibernateAfterTimeoutmilliseconds and if no message is received, the process goes into hibernation automatically (by callingproc_lib:hibernate/3). -
If option
{debug,Dbgs}is present, the correspondingsysfunction is called for each item inDbgs; seesys(3). -
If option
{spawn_opt,SOpts}is present,SOptsis passed as option list to thespawn_optBIF, which is used to spawn thegen_serverprocess; seespawn_opt/2.
Note!
Using spawn option monitor is not
allowed, it causes the function to fail with reason
badarg.
If the gen_server process is successfully created and
initialized, the function returns {ok,Pid}, where Pid
is the pid of the gen_server process. If a process with the
specified ServerName exists already, the function returns
{error,{already_started,Pid}}, where Pid is
the pid of that process.
If Module:init/1 fails with Reason,
the function returns {error,Reason}. If
Module:init/1 returns {stop,Reason} or
ignore, the process is terminated and the function
returns {error,Reason} or ignore, respectively.
ServerRef = Name | {Name,Node} | {global,GlobalName}��| {via,Module,ViaName} | pid()�Node = atom()�GlobalName = ViaName = term()Reason = term()Timeout = int()>0 | infinity
Orders a generic server to exit with the specified Reason
and waits for it to terminate. The gen_server process calls
Module:terminate/2 before exiting.
The function returns ok if the server terminates
with the expected reason. Any other reason than normal,
shutdown, or {shutdown,Term} causes an
error report to be issued using
logger(3).
The default Reason is normal.
Timeout is an integer greater than zero that
specifies how many milliseconds to wait for the server to
terminate, or the atom infinity to wait
indefinitely. Defaults to infinity. If the
server has not terminated within the specified time, a
timeout exception is raised.
If the process does not exist, a noproc exception
is raised.
Callback Functions
The following functions
are to be exported from a gen_server callback module.
Functions
OldVsn = Vsn | {down, Vsn}��Vsn = term()State = NewState = term()Extra = term()Reason = term()
Note!
This callback is optional, so callback modules need not export it.
If a release upgrade/downgrade with Change={advanced,Extra}
specified in the appup file is made when code_change/3
isn't implemented the process will crash with an undef exit
reason.
This function is called by a gen_server process when it is
to update its internal state during a release upgrade/downgrade,
that is, when the instruction {update,Module,Change,...},
where Change={advanced,Extra}, is specifed in
the appup file. For more information, see section
Release Handling Instructions in OTP Design Principles.
For an upgrade, OldVsn is Vsn, and
for a downgrade, OldVsn is
{down,Vsn}. Vsn is defined by the vsn
attribute(s) of the old version of the callback module
Module. If no such attribute is defined, the version
is the checksum of the Beam file.
State is the internal state of the gen_server
process.
Extra is passed "as is" from the {advanced,Extra}
part of the update instruction.
If successful, the function must return the updated internal state.
If the function returns {error,Reason}, the ongoing
upgrade fails and rolls back to the old release.
Opt = normal | terminatePDict = [{Key, Value}]State = term()Status = term()
Note!
This callback is optional, so callback modules need not
export it. The gen_server module provides a default
implementation of this function that returns the callback
module state.
This function is called by a gen_server process in the
following situations:
-
One of
sys:get_status/1,2is invoked to get thegen_serverstatus.Optis set to the atomnormal. -
The
gen_serverprocess terminates abnormally and logs an error.Optis set to the atomterminate.
This function is useful for changing the form and
appearance of the gen_server status for these cases. A
callback module wishing to change
the sys:get_status/1,2 return value, as well as how
its status appears in termination error logs, exports an
instance of format_status/2 that returns a term
describing the current status of the gen_server process.
PDict is the current value of the process dictionary of
the gen_server process..
State is the internal state of the gen_server
process.
The function is to return Status, a term that
changes the details of the current state and status of
the gen_server process. There are no restrictions on the
form Status can take, but for
the sys:get_status/1,2 case (when Opt
is normal), the recommended form for
the Status value is [{data, [{"State",
Term}]}], where Term provides relevant details of
the gen_server state. Following this recommendation is not
required, but it makes the callback module status
consistent with the rest of the sys:get_status/1,2
return value.
One use for this function is to return compact alternative state representations to avoid that large state terms are printed in log files.
Request = term()From = {pid(),Tag}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()
Whenever a gen_server process receives a request sent using
call/2,3 or
multi_call/2,3,4,
this function is called to handle the request.
Request is the Request argument provided
to call or multi_call.
From is a tuple {Pid,Tag}, where Pid is
the pid of the client and Tag is a unique tag.
State is the internal state of the gen_server
process.
-
If
{reply,Reply,NewState}is returned,{reply,Reply,NewState,Timeout}or{reply,Reply,NewState,hibernate},Replyis given back toFromas the return value ofcall/2,3or included in the return value ofmulti_call/2,3,4. Thegen_serverprocess then continues executing with the possibly updated internal stateNewState.For a description of
Timeoutandhibernate, seeModule:init/1. -
If
{noreply,NewState}is returned,{noreply,NewState,Timeout}, or{noreply,NewState,hibernate}, thegen_serverprocess continues executing withNewState. Any reply toFrommust be specified explicitly usingreply/2. -
If
{stop,Reason,Reply,NewState}is returned,Replyis given back toFrom. -
If
{stop,Reason,NewState}is returned, any reply toFrommust be specified explicitly usingreply/2. Thegen_serverprocess then callsModule:terminate(Reason,NewState)and terminates.
Request = 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 = term()
Whenever a gen_server process receives a request sent using
cast/2 or
abcast/2,3,
this function is called to handle the request.
For a description of the arguments and possible return values, see
Module:handle_call/3.
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()
Note!
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.
Info = timeout | 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�Reason = normal | term()
Note!
This callback is optional, so callback modules need not
export it. The gen_server module provides a default
implementation of this function that logs about the unexpected
Info message, drops it and returns {noreply, State}.
This function is called by a gen_server process when a
time-out occurs or when it receives any other message than a
synchronous or asynchronous request (or a system message).
Info is either the atom timeout, if a time-out
has occurred, or the received message.
For a description of the other arguments and possible return values,
see
Module:handle_call/3.
Args = term()Result = {ok,State} | {ok,State,Timeout} | {ok,State,hibernate}�| {ok,State,{continue,Continue}} | {stop,Reason} | ignore�State = term()�Timeout = int()>=0 | infinity�Reason = term()
Whenever a gen_server process is started using
start/3,4 or
start_link/3,4,
this function is called by the new process to initialize.
Args is the Args argument provided to the start
function.
If the initialization is successful, the function is to
return {ok,State}, {ok,State,Timeout}, or
{ok,State,hibernate}, where State is the internal
state of the gen_server process.
If an integer time-out value is provided, a time-out occurs
unless a request or a message is received within
Timeout milliseconds. A time-out is represented by
the atom timeout, which is to be handled by the
Module:handle_info/2 callback function. The atom
infinity can be used to wait indefinitely, this is
the default value.
If hibernate is specified instead of a time-out value,
the process goes into
hibernation when waiting for the next message to arrive (by calling
proc_lib:hibernate/3).
If the initialization fails, the function is to return
{stop,Reason}, where Reason is any term, or
ignore.
Reason = normal | shutdown | {shutdown,term()} | term()State = term()
Note!
This callback is optional, so callback modules need not
export it. The gen_server module provides a default
implementation without cleanup.
This function is called by a gen_server process when it is
about to terminate. It is to be the opposite of
Module:init/1
and do any necessary cleaning up. When it returns,
the gen_server process terminates with Reason.
The return value is ignored.
Reason is a term denoting the stop reason and State
is the internal state of the gen_server process.
Reason depends on why the gen_server process is
terminating. If it is because another callback function has returned
a stop tuple {stop,..}, Reason has
the value specified in that tuple. If it is because of a failure,
Reason is the error reason.
If the gen_server process is part of a supervision tree and
is ordered by its supervisor to terminate, this function is
called with Reason=shutdown if the following
conditions apply:
-
The
gen_serverprocess has been set to trap exit signals. -
The shutdown strategy as defined in the child specification of the supervisor is an integer time-out value, not
brutal_kill.
Even if the gen_server process is not part of a
supervision tree, this function is called if it receives an
'EXIT' message from its parent. Reason is the same
as in the 'EXIT' message.
Otherwise, the gen_server process terminates immediately.
Notice that for any other reason than normal,
shutdown, or {shutdown,Term}, the gen_server
process is assumed to terminate because of an error and
an error report is issued using
logger(3).
See Also
gen_event(3),
gen_statem(3),
proc_lib(3),
supervisor(3),
sys(3)