table of contents
other versions
- jessie 1:17.3-dfsg-4+deb8u2
- jessie-backports 1:19.2.1+dfsg-2+deb9u1~bpo8+1
- stretch 1:19.2.1+dfsg-2+deb9u2
- testing 1:21.2.5+dfsg-1
- unstable 1:21.2.6+dfsg-1
- experimental 1:22.0~rc1+dfsg-1
gen_server(3erl) | Erlang Module Definition | gen_server(3erl) |
NAME¶
gen_server - Generic server behavior.DESCRIPTION¶
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:terminate/2 - -----> Module:code_change/3If 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(3erl). 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.
EXPORTS¶
abcast(Name, Request) -> abcast
Types:
Nodes = [Node]
Node = atom()
Name = atom()
Request = term()
Node = atom()
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.
call(ServerRef, Request) -> Reply
Types:
ServerRef = Name | {Name,Node} | {global,GlobalName}
| {via,Module,ViaName} | pid()
Node = atom()
GlobalName = ViaName = term()
Request = term()
Timeout = int()>0 | infinity
Reply = term()
| {via,Module,ViaName} | pid()
Node = atom()
GlobalName = ViaName = 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:
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.
cast(ServerRef, Request) -> ok
- *
- The pid
- *
- Name, if the gen_server process is locally registered
- *
- {Name,Node}, if the gen_server process is locally registered at another node
- *
- {global,GlobalName}, if the gen_server process is globally registered
- *
- {via,Module,ViaName}, if the gen_server process is registered through an alternative process registry
Note:
The ancient behavior of sometimes consuming the server exit message if the
server died during the call while linked to the client was removed in Erlang
5.6/OTP R12B.
Types:
ServerRef = Name | {Name,Node} | {global,GlobalName}
| {via,Module,ViaName} | pid()
Node = atom()
GlobalName = ViaName = term()
Request = term()
| {via,Module,ViaName} | pid()
Node = atom()
GlobalName = ViaName = 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.
enter_loop(Module, Options, State)
Types:
Module = atom()
Options = [Option]
Option = {debug,Dbgs}
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
Option = {debug,Dbgs}
Dbgs = [Dbg]
Dbg = trace | log | statistics
| {log_to_file,FileName} | {install,{Func,FuncState}}
| {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
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(3erl). 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.
multi_call(Name, Request) -> Result
Types:
Nodes = [Node]
Node = atom()
Name = atom()
Request = term()
Timeout = int()>=0 | infinity
Result = {Replies,BadNodes}
Replies = [{Node,Reply}]
Reply = term()
BadNodes = [Node]
Node = atom()
Replies = [{Node,Reply}]
Reply = term()
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.
reply(Client, Reply) -> Result
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.
Types:
Client - see below
Reply = 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.
start(Module, Args, Options) -> Result
Types:
ServerName = {local,Name} | {global,GlobalName}
| {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Module = atom()
Args = term()
Options = [Option]
Option = {debug,Dbgs} | {timeout,Time} | {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()
| {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}
Dbgs = [Dbg]
Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
SOpts = [term()]
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.
start_link(Module, Args, Options) -> Result
Types:
ServerName = {local,Name} | {global,GlobalName}
| {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Module = atom()
Args = term()
Options = [Option]
Option = {debug,Dbgs} | {timeout,Time} | {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()
| {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}
Dbgs = [Dbg]
Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
SOpts = [term()]
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.
Module is the name of the callback module.
Args is any term that is passed as the argument to
Module:init/1.
stop(ServerRef) -> ok
- *
- If ServerName={local,Name}, the gen_server process is registered locally as Name using register/2.
- *
- If ServerName={global,GlobalName}, the gen_server process id registered globally as GlobalName using global:register_name/2 If no name is provided, the gen_server process is not registered.
- *
- If ServerName={via,Module,ViaName}, the gen_server process registers with the registry represented by Module. The Module callback is to export the functions register_name/2, unregister_name/1, whereis_name/1, and send/2, which are to behave like the corresponding functions in global. Thus, {via,global,GlobalName} is a valid reference.
- *
- If option {timeout,Time} is present, the gen_server process is allowed to spend Time milliseconds initializing or it is terminated and the start function returns {error,timeout}.
- *
- If option {debug,Dbgs} is present, the corresponding sys function is called for each item in Dbgs; see sys(3erl).
- *
- If option {spawn_opt,SOpts} is present, SOpts is passed as option list to the spawn_opt BIF, which is used to spawn the gen_server process; see spawn_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.
Types:
ServerRef = Name | {Name,Node} | {global,GlobalName}
| {via,Module,ViaName} | pid()
Node = atom()
GlobalName = ViaName = term()
Reason = term()
Timeout = int()>0 | infinity
| {via,Module,ViaName} | pid()
Node = atom()
GlobalName = ViaName = term()
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
error_logger:format/2. 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.EXPORTS¶
Module:code_change(OldVsn, State, Extra) -> {ok, NewState} | {error, Reason}
Types:
OldVsn = Vsn | {down, Vsn}
Vsn = term()
State = NewState = term()
Extra = term()
Reason = term()
Vsn = term()
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.
Module:format_status(Opt, [PDict, State]) -> Status
Types:
Opt = normal | terminate
PDict = [{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,2 is invoked to get the gen_server status. Opt is set to the atom normal.
- *
- The gen_server process terminates abnormally and logs an error. Opt is set to the atom terminate.
Types:
Request = term()
From = {pid(),Tag}
State = term()
Result = {reply,Reply,NewState} | {reply,Reply,NewState,Timeout}
| {reply,Reply,NewState,hibernate}
| {noreply,NewState} | {noreply,NewState,Timeout}
| {noreply,NewState,hibernate}
| {stop,Reason,Reply,NewState} | {stop,Reason,NewState}
Reply = term()
NewState = term()
Timeout = int()>=0 | infinity
Reason = term()
| {reply,Reply,NewState,hibernate}
| {noreply,NewState} | {noreply,NewState,Timeout}
| {noreply,NewState,hibernate}
| {stop,Reason,Reply,NewState} | {stop,Reason,NewState}
Reply = term()
NewState = term()
Timeout = int()>=0 | infinity
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.
Module:handle_cast(Request, State) -> Result
- *
- If {reply,Reply,NewState} is returned, {reply,Reply,NewState,Timeout} or {reply,Reply,NewState,hibernate}, Reply is given back to From as the return value of call/2,3 or included in the return value of multi_call/2,3,4. The gen_server process then continues executing with the possibly updated internal state NewState.
For a description of Timeout and hibernate, see
Module:init/1.
- *
- If {noreply,NewState} is returned, {noreply,NewState,Timeout}, or {noreply,NewState,hibernate}, the gen_server process continues executing with NewState. Any reply to From must be specified explicitly using reply/2.
- *
- If {stop,Reason,Reply,NewState} is returned, Reply is given back to From.
- *
- If {stop,Reason,NewState} is returned, any reply to From must be specified explicitly using reply/2. The gen_server process then calls Module:terminate(Reason,NewState) and terminates.
Types:
Request = term()
State = term()
Result = {noreply,NewState} | {noreply,NewState,Timeout}
| {noreply,NewState,hibernate}
| {stop,Reason,NewState}
NewState = term()
Timeout = int()>=0 | infinity
Reason = term()
| {noreply,NewState,hibernate}
| {stop,Reason,NewState}
NewState = term()
Timeout = int()>=0 | infinity
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.
Module:handle_info(Info, State) -> Result
Types:
Info = timeout | term()
State = term()
Result = {noreply,NewState} | {noreply,NewState,Timeout}
| {noreply,NewState,hibernate}
| {stop,Reason,NewState}
NewState = term()
Timeout = int()>=0 | infinity
Reason = normal | term()
| {noreply,NewState,hibernate}
| {stop,Reason,NewState}
NewState = term()
Timeout = int()>=0 | infinity
Reason = normal | term()
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.
Module:init(Args) -> Result
Types:
Args = term()
Result = {ok,State} | {ok,State,Timeout} | {ok,State,hibernate}
| {stop,Reason} | ignore
State = term()
Timeout = int()>=0 | infinity
Reason = term()
| {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.
Module:terminate(Reason, State)
Types:
Reason = normal | shutdown | {shutdown,term()} | term()
State = term()
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:
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
error_logger:format/2.
- *
- The gen_server process 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.
SEE ALSO¶
gen_event(3erl), gen_fsm(3erl), gen_statem(3erl), proc_lib(3erl), supervisor(3erl), sys(3erl)stdlib 3.2 | Ericsson AB |