aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/design_principles/gen_server_concepts.xml
diff options
context:
space:
mode:
Diffstat (limited to 'system/doc/design_principles/gen_server_concepts.xml')
-rw-r--r--system/doc/design_principles/gen_server_concepts.xml160
1 files changed, 83 insertions, 77 deletions
diff --git a/system/doc/design_principles/gen_server_concepts.xml b/system/doc/design_principles/gen_server_concepts.xml
index d24d87aa03..d721845c6d 100644
--- a/system/doc/design_principles/gen_server_concepts.xml
+++ b/system/doc/design_principles/gen_server_concepts.xml
@@ -21,7 +21,7 @@
</legalnotice>
- <title>Gen_Server Behaviour</title>
+ <title>gen_server Behaviour</title>
<prepared></prepared>
<docno></docno>
<date></date>
@@ -29,16 +29,16 @@
<file>gen_server_concepts.xml</file>
</header>
<marker id="gen_server"></marker>
- <p>This chapter should be read in conjunction with
- <seealso marker="stdlib:gen_server">gen_server(3)</seealso>,
- where all interface functions and callback
- functions are described in detail.</p>
+ <p>This section is to be read with the
+ <seealso marker="stdlib:gen_server">gen_server(3)</seealso>
+ manual page in <c>stdblib</c>, where all interface functions and
+ callback functions are described in detail.</p>
<section>
<title>Client-Server Principles</title>
<p>The client-server model is characterized by a central server
and an arbitrary number of clients. The client-server model is
- generally used for resource management operations, where several
+ used for resource management operations, where several
different clients want to share a common resource. The server is
responsible for managing this resource.</p>
<marker id="clientserver"></marker>
@@ -49,9 +49,10 @@
<section>
<title>Example</title>
- <p>An example of a simple server written in plain Erlang was
- given in <seealso marker="des_princ#ch1">Overview</seealso>.
- The server can be re-implemented using <c>gen_server</c>,
+ <p>An example of a simple server written in plain Erlang is
+ provided in
+ <seealso marker="des_princ#ch1">Overview</seealso>.
+ The server can be reimplemented using <c>gen_server</c>,
resulting in this callback module:</p>
<marker id="ex"></marker>
<code type="none">
@@ -86,61 +87,60 @@ handle_cast({free, Ch}, Chs) ->
<section>
<title>Starting a Gen_Server</title>
- <p>In the example in the previous section, the gen_server is started
- by calling <c>ch3:start_link()</c>:</p>
+ <p>In the example in the previous section, <c>gen_server</c> is
+ started by calling <c>ch3:start_link()</c>:</p>
<code type="none">
start_link() ->
gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}</code>
- <p><c>start_link</c> calls the function
- <c>gen_server:start_link/4</c>. This function spawns and links to
- a new process, a gen_server.</p>
+ <p><c>start_link</c> calls function <c>gen_server:start_link/4</c>.
+ This function spawns and links to a new process, a
+ <c>gen_server</c>.</p>
<list type="bulleted">
<item>
- <p>The first argument <c>{local, ch3}</c> specifies the name. In
- this case, the gen_server will be locally registered as
- <c>ch3</c>.</p>
- <p>If the name is omitted, the gen_server is not registered.
- Instead its pid must be used. The name could also be given
- as <c>{global, Name}</c>, in which case the gen_server is
+ <p>The first argument, <c>{local, ch3}</c>, specifies the name.
+ The gen_server is then locally registered as <c>ch3</c>.</p>
+ <p>If the name is omitted, the <c>gen_server</c> is not registered.
+ Instead its pid must be used. The name can also be given
+ as <c>{global, Name}</c>, in which case the <c>gen_server</c> is
registered using <c>global:register_name/2</c>.</p>
</item>
<item>
<p>The second argument, <c>ch3</c>, is the name of the callback
- module, that is the module where the callback functions are
+ module, that is, the module where the callback functions are
located.</p>
- <p>In this case, the interface functions (<c>start_link</c>,
- <c>alloc</c> and <c>free</c>) are located in the same module
- as the callback functions (<c>init</c>, <c>handle_call</c> and
+ <p>The interface functions (<c>start_link</c>, <c>alloc</c>,
+ and <c>free</c>) are then located in the same module
+ as the callback functions (<c>init</c>, <c>handle_call</c>, and
<c>handle_cast</c>). This is normally good programming
practice, to have the code corresponding to one process
contained in one module.</p>
</item>
<item>
- <p>The third argument, [], is a term which is passed as-is to
- the callback function <c>init</c>. Here, <c>init</c> does not
+ <p>The third argument, <c>[]</c>, is a term that is passed as is
+ to the callback function <c>init</c>. Here, <c>init</c> does not
need any indata and ignores the argument.</p>
</item>
<item>
- <p>The fourth argument, [], is a list of options. See
- <c>gen_server(3)</c> for available options.</p>
+ <p>The fourth argument, <c>[]</c>, is a list of options. See the
+ <c>gen_server(3)</c> manual page for available options.</p>
</item>
</list>
- <p>If name registration succeeds, the new gen_server process calls
- the callback function <c>ch3:init([])</c>. <c>init</c> is expected
- to return <c>{ok, State}</c>, where <c>State</c> is the internal
- state of the gen_server. In this case, the state is the available
- channels.</p>
+ <p>If name registration succeeds, the new <c>gen_server</c> process
+ calls the callback function <c>ch3:init([])</c>. <c>init</c> is
+ expected to return <c>{ok, State}</c>, where <c>State</c> is the
+ internal state of the <c>gen_server</c>. In this case, the state
+ is the available channels.</p>
<code type="none">
init(_Args) ->
{ok, channels()}.</code>
- <p>Note that <c>gen_server:start_link</c> is synchronous. It does
- not return until the gen_server has been initialized and is ready
+ <p><c>gen_server:start_link</c> is synchronous. It does not return
+ until the <c>gen_server</c> has been initialized and is ready
to receive requests.</p>
- <p><c>gen_server:start_link</c> must be used if the gen_server is
- part of a supervision tree, i.e. is started by a supervisor.
- There is another function <c>gen_server:start</c> to start a
- stand-alone gen_server, i.e. a gen_server which is not part of a
- supervision tree.</p>
+ <p><c>gen_server:start_link</c> must be used if the <c>gen_server</c>
+ is part of a supervision tree, that is, started by a supervisor.
+ There is another function, <c>gen_server:start</c>, to start a
+ standalone <c>gen_server</c>, that is, a <c>gen_server</c> that
+ is not part of a supervision tree.</p>
</section>
<section>
@@ -150,14 +150,17 @@ init(_Args) ->
<code type="none">
alloc() ->
gen_server:call(ch3, alloc).</code>
- <p><c>ch3</c> is the name of the gen_server and must agree with
- the name used to start it. <c>alloc</c> is the actual request.</p>
- <p>The request is made into a message and sent to the gen_server.
- When the request is received, the gen_server calls
- <c>handle_call(Request, From, State)</c> which is expected to
- return a tuple <c>{reply, Reply, State1}</c>. <c>Reply</c> is
- the reply which should be sent back to the client, and
- <c>State1</c> is a new value for the state of the gen_server.</p>
+ <p><c>ch3</c> is the name of the <c>gen_server</c> and must agree
+ with the name used to start it. <c>alloc</c> is the actual
+ request.</p>
+ <p>The request is made into a message and sent to the
+ <c>gen_server</c>. When the request is received, the
+ <c>gen_server</c> calls
+ <c>handle_call(Request, From, State)</c>, which is expected to
+ return a tuple <c>{reply,Reply,State1}</c>. <c>Reply</c> is
+ the reply that is to be sent back to the client, and
+ <c>State1</c> is a new value for the state of the
+ <c>gen_server</c>.</p>
<code type="none">
handle_call(alloc, _From, Chs) ->
{Ch, Chs2} = alloc(Chs),
@@ -166,8 +169,8 @@ handle_call(alloc, _From, Chs) ->
the new state is the set of remaining available channels
<c>Chs2</c>.</p>
<p>Thus, the call <c>ch3:alloc()</c> returns the allocated channel
- <c>Ch</c> and the gen_server then waits for new requests, now
- with an updated list of available channels.</p>
+ <c>Ch</c> and the <c>gen_server</c> then waits for new requests,
+ now with an updated list of available channels.</p>
</section>
<section>
@@ -177,20 +180,21 @@ handle_call(alloc, _From, Chs) ->
<code type="none">
free(Ch) ->
gen_server:cast(ch3, {free, Ch}).</code>
- <p><c>ch3</c> is the name of the gen_server. <c>{free, Ch}</c> is
- the actual request.</p>
- <p>The request is made into a message and sent to the gen_server.
+ <p><c>ch3</c> is the name of the <c>gen_server</c>.
+ <c>{free, Ch}</c> is the actual request.</p>
+ <p>The request is made into a message and sent to the
+ <c>gen_server</c>.
<c>cast</c>, and thus <c>free</c>, then returns <c>ok</c>.</p>
- <p>When the request is received, the gen_server calls
- <c>handle_cast(Request, State)</c> which is expected to
- return a tuple <c>{noreply, State1}</c>. <c>State1</c> is a new
- value for the state of the gen_server.</p>
+ <p>When the request is received, the <c>gen_server</c> calls
+ <c>handle_cast(Request, State)</c>, which is expected to
+ return a tuple <c>{noreply,State1}</c>. <c>State1</c> is a new
+ value for the state of the <c>gen_server</c>.</p>
<code type="none">
handle_cast({free, Ch}, Chs) ->
Chs2 = free(Ch, Chs),
{noreply, Chs2}.</code>
<p>In this case, the new state is the updated list of available
- channels <c>Chs2</c>. The gen_server is now ready for new
+ channels <c>Chs2</c>. The <c>gen_server</c> is now ready for new
requests.</p>
</section>
@@ -199,15 +203,17 @@ handle_cast({free, Ch}, Chs) ->
<section>
<title>In a Supervision Tree</title>
- <p>If the gen_server is part of a supervision tree, no stop
- function is needed. The gen_server will automatically be
+ <p>If the <c>gen_server</c> is part of a supervision tree, no stop
+ function is needed. The <c>gen_server</c> is automatically
terminated by its supervisor. Exactly how this is done is
- defined by a <seealso marker="sup_princ#shutdown">shutdown strategy</seealso> set in the supervisor.</p>
+ defined by a
+ <seealso marker="sup_princ#shutdown">shutdown strategy</seealso>
+ set in the supervisor.</p>
<p>If it is necessary to clean up before termination, the shutdown
- strategy must be a timeout value and the gen_server must be set
- to trap exit signals in the <c>init</c> function. When ordered
- to shutdown, the gen_server will then call the callback function
- <c>terminate(shutdown, State)</c>:</p>
+ strategy must be a time-out value and the <c>gen_server</c> must
+ be set to trap exit signals in function <c>init</c>. When ordered
+ to shutdown, the <c>gen_server</c> then calls the callback
+ function <c>terminate(shutdown, State)</c>:</p>
<code type="none">
init(Args) ->
...,
@@ -223,9 +229,9 @@ terminate(shutdown, State) ->
</section>
<section>
- <title>Stand-Alone Gen_Servers</title>
- <p>If the gen_server is not part of a supervision tree, a stop
- function may be useful, for example:</p>
+ <title>Standalone Gen_Servers</title>
+ <p>If the <c>gen_server</c> is not part of a supervision tree, a
+ stop function can be useful, for example:</p>
<code type="none">
...
export([stop/0]).
@@ -245,26 +251,26 @@ handle_cast({free, Ch}, State) ->
terminate(normal, State) ->
ok.</code>
<p>The callback function handling the <c>stop</c> request returns
- a tuple <c>{stop, normal, State1}</c>, where <c>normal</c>
+ a tuple <c>{stop,normal,State1}</c>, where <c>normal</c>
specifies that it is a normal termination and <c>State1</c> is
- a new value for the state of the gen_server. This will cause
- the gen_server to call <c>terminate(normal,State1)</c> and then
- terminate gracefully.</p>
+ a new value for the state of the <c>gen_server</c>. This causes
+ the <c>gen_server</c> to call <c>terminate(normal, State1)</c>
+ and then it terminates gracefully.</p>
</section>
</section>
<section>
<title>Handling Other Messages</title>
- <p>If the gen_server should be able to receive other messages than
- requests, the callback function <c>handle_info(Info, State)</c>
+ <p>If the <c>gen_server</c> is to be able to receive other messages
+ than requests, the callback function <c>handle_info(Info, State)</c>
must be implemented to handle them. Examples of other messages
- are exit messages, if the gen_server is linked to other processes
- (than the supervisor) and trapping exit signals.</p>
+ are exit messages, if the <c>gen_server</c> is linked to other
+ processes (than the supervisor) and trapping exit signals.</p>
<code type="none">
handle_info({'EXIT', Pid, Reason}, State) ->
..code to handle exits here..
{noreply, State1}.</code>
- <p>The code_change method also has to be implemented.</p>
+ <p>The <c>code_change</c> method must also be implemented.</p>
<code type="none">
code_change(OldVsn, State, Extra) ->
..code to convert state (and more) during code change