From 42a0387e886ddbf60b0e2cb977758e2ca74954ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 12 Mar 2015 15:35:13 +0100 Subject: Update Design Principles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language cleaned up by the technical writers xsipewe and tmanevik from Combitech. Proofreading and corrections by Björn Gustavsson. --- system/doc/design_principles/spec_proc.xml | 214 ++++++++++++++--------------- 1 file changed, 103 insertions(+), 111 deletions(-) (limited to 'system/doc/design_principles/spec_proc.xml') diff --git a/system/doc/design_principles/spec_proc.xml b/system/doc/design_principles/spec_proc.xml index e849388a38..aceb5ba99e 100644 --- a/system/doc/design_principles/spec_proc.xml +++ b/system/doc/design_principles/spec_proc.xml @@ -21,30 +21,31 @@ - Sys and Proc_Lib + sys and proc_lib spec_proc.xml -

The module sys contains functions for simple debugging of - processes implemented using behaviours.

-

There are also functions that, together with functions in - the module proc_lib, can be used to implement a - special process, a process which comply to the OTP design - principles without making use of a standard behaviour. They can - also be used to implement user defined (non-standard) behaviours.

-

Both sys and proc_lib belong to the STDLIB - application.

+ +

The sys module has functions for simple debugging of + processes implemented using behaviours. It also has functions that, + together with functions in the proc_lib module, can be used + to implement a special process that complies to the OTP + design principles without using a standard behaviour. These + functions can also be used to implement user-defined (non-standard) + behaviours.

+

Both sys and proc_lib belong to the STDLIB + application.

Simple Debugging -

The module sys contains some functions for simple debugging - of processes implemented using behaviours. We use the - code_lock example from - the gen_fsm chapter to - illustrate this:

+

The sys module has functions for simple debugging of + processes implemented using behaviours. The code_lock + example from + gen_fsm Behaviour + is used to illustrate this:

 % erl
 Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
@@ -102,16 +103,18 @@ ok
 
   
Special Processes -

This section describes how to write a process which comply to - the OTP design principles, without making use of a standard - behaviour. Such a process should:

+

This section describes how to write a process that complies to + the OTP design principles, without using a standard behaviour. + Such a process is to:

- be started in a way that makes the process fit into a - supervision tree, - support the sys debug facilities, and - take care of system messages. + Be started in a way that makes the process fit into a + supervision tree + Support the sys + debug facilities + Take care of + system messages. -

System messages are messages with special meaning, used in +

System messages are messages with a special meaning, used in the supervision tree. Typical system messages are requests for trace output, and requests to suspend or resume process execution (used during release handling). Processes implemented using @@ -120,9 +123,9 @@ ok

Example

The simple server from - the Overview chapter, - implemented using sys and proc_lib so it fits into - a supervision tree:

+ Overview, + implemented using sys and proc_lib so it fits into a + supervision tree:

 -module(ch4).
@@ -190,8 +193,8 @@ system_replace_state(StateFun, Chs) ->
 
 write_debug(Dev, Event, Name) ->
     io:format(Dev, "~p event = ~p~n", [Name, Event]).
-

Example on how the simple debugging functions in sys can - be used for ch4 as well:

+

Example on how the simple debugging functions in the sys + module can also be used for ch4:

 % erl
 Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
@@ -230,31 +233,32 @@ ok
 
     
Starting the Process -

A function in the proc_lib module should be used to - start the process. There are several possible functions, for - example spawn_link/3,4 for asynchronous start and +

A function in the proc_lib module is to be used to + start the process. Several functions are available, for + example, spawn_link/3,4 for asynchronous start and start_link/3,4,5 for synchronous start.

-

A process started using one of these functions will store - information that is needed for a process in a supervision tree, - for example about the ancestors and initial call.

-

Also, if the process terminates with another reason than - normal or shutdown, a crash report (see SASL - User's Guide) is generated.

-

In the example, synchronous start is used. The process is - started by calling ch4:start_link():

+

A process started using one of these functions stores + information (for example, about the ancestors and initial call) + that is needed for a process in a supervision tree.

+

If the process terminates with another reason than + normal or shutdown, a crash report is generated. + For more information about the crash report, see the SASL + User's Guide.

+

In the example, synchronous start is used. The process + starts by calling ch4:start_link():

start_link() -> proc_lib:start_link(ch4, init, [self()]).

ch4:start_link calls the function proc_lib:start_link. This function takes a module name, - a function name and an argument list as arguments and spawns + a function name, and an argument list as arguments, spawns, and links to a new process. The new process starts by executing - the given function, in this case ch4:init(Pid), where - Pid is the pid (self()) of the first process, that - is the parent process.

-

In init, all initialization including name registration - is done. The new process must also acknowledge that it has been - started to the parent:

+ the given function, here ch4:init(Pid), where + Pid is the pid (self()) of the first process, + which is the parent process.

+

All initialization, including name registration, is done in + init. The new process must also acknowledge that it has + been started to the parent:

init(Parent) -> ... @@ -267,8 +271,8 @@ init(Parent) ->
Debugging -

To support the debug facilites in sys, we need a - debug structure, a term Deb which is +

To support the debug facilites in sys, a + debug structure is needed. The Deb term is initialized using sys:debug_options/1:

init(Parent) -> @@ -278,50 +282,41 @@ init(Parent) -> loop(Chs, Parent, Deb).

sys:debug_options/1 takes a list of options as argument. Here the list is empty, which means no debugging is enabled - initially. See sys(3) for information about possible - options.

-

Then for each system event that we want to be logged - or traced, the following function should be called.

+ initially. For information about the possible options, see the + sys(3) manual page in STDLIB.

+

Then, for each system event to be logged + or traced, the following function is to be called.

sys:handle_debug(Deb, Func, Info, Event) => Deb1 +

Here:

- -

Deb is the debug structure.

-
- -

Func is a fun specifying - a (user defined) function used to format + Deb is the debug structure. + Func is a fun specifying + a (user-defined) function used to format trace output. For each system event, the format function is - called as Func(Dev, Event, Info), where:

+ called as Func(Dev, Event, Info), where: - -

Dev is the IO device to which the output should - be printed. See io(3).

-
- -

Event and Info are passed as-is from - handle_debug.

-
+ Dev is the I/O device to which the output is to + be printed. See the io(3) manual page in + STDLIB. + Event and Info are passed as is from + handle_debug.
- -

Info is used to pass additional information to - Func, it can be any term and is passed as-is.

-
- -

Event is the system event. It is up to the user to - define what a system event is and how it should be - represented, but typically at least incoming and outgoing + Info is used to pass more information to + Func. It can be any term and is passed as is. + Event is the system event. It is up to the user to + define what a system event is and how it is to be + represented. Typically at least incoming and outgoing messages are considered system events and represented by the tuples {in,Msg[,From]} and {out,Msg,To}, - respectively.

-
+ respectively.

handle_debug returns an updated debug structure Deb1.

In the example, handle_debug is called for each incoming and outgoing message. The format function Func is - the function ch4:write_debug/3 which prints the message + the function ch4:write_debug/3, which prints the message using io:format/3.

loop(Chs, Parent, Deb) -> @@ -354,22 +349,22 @@ write_debug(Dev, Event, Name) -> {system, From, Request}

The content and meaning of these messages do not need to be interpreted by the process. Instead the following function - should be called:

+ is to be called:

sys:handle_system_msg(Request, From, Parent, Module, Deb, State) -

This function does not return. It will handle the system - message and then call:

+

This function does not return. It handles the system + message and then either calls the following if process execution is + to continue:

Module:system_continue(Parent, Deb, State) -

if process execution should continue, or:

+

Or calls the following if the process is to terminate:

Module:system_terminate(Reason, Parent, Deb, State) -

if the process should terminate. Note that a process in a - supervision tree is expected to terminate with the same reason as - its parent.

+

A process in a supervision tree is expected to terminate with + the same reason as its parent.

- Request and From should be passed as-is from - the system message to the call to handle_system_msg. + Request and From are to be passed as is from + the system message to the call to handle_system_msg. Parent is the pid of the parent. Module is the name of the module. Deb is the debug structure. @@ -377,10 +372,12 @@ Module:system_terminate(Reason, Parent, Deb, State)
is passed to system_continue/system_terminate/ system_get_state/system_replace_state. -

If the process should return its state handle_system_msg will call:

+

If the process is to return its state, handle_system_msg + calls:

Module:system_get_state(State) -

or if the process should replace its state using the fun StateFun:

+

If the process is to replace its state using the fun StateFun, + handle_system_msg calls:

Module:system_replace_state(StateFun, State)

In the example:

@@ -407,9 +404,9 @@ system_replace_state(StateFun, Chs) -> NChs = StateFun(Chs), {ok, NChs, NChs}. -

If the special process is set to trap exits, note that if - the parent process terminates, the expected behavior is to - terminate with the same reason:

+

If the special process is set to trap exits and if the parent + process terminates, the expected behavior is to terminate with + the same reason:

init(...) -> ..., @@ -431,28 +428,23 @@ loop(...) ->
User-Defined Behaviours -

To implement a user-defined behaviour, - write code similar to code for a special process but calling - functions in a callback module for handling specific tasks.

-

If it is desired that the compiler should warn for missing - callback functions, as it does for the OTP behaviours, add - -callback attributes in the behaviour module to describe - the expected callback functions:

- + write code similar to + code for a special process, but call functions in a callback + module for handling specific tasks.

+

If the compiler is to warn for missing callback functions, as it + does for the OTP behaviours, add -callback attributes in the + behaviour module to describe the expected callbacks:

-callback Name1(Arg1_1, Arg1_2, ..., Arg1_N1) -> Res1. -callback Name2(Arg2_1, Arg2_2, ..., Arg2_N2) -> Res2. ... -callback NameM(ArgM_1, ArgM_2, ..., ArgM_NM) -> ResM. - -

where each Name is the name of a callback function and - Arg and Res are types as described in - Specifications for functions in Types and Function - Specifications. The whole syntax of the - -spec attribute is supported by -callback - attribute.

+

NameX are the names of the expected callbacks. + ArgX_Y and ResX are types as they are described in + Types and + Function Specifications. The whole syntax of the -spec + attribute is supported by the -callback attribute.

Callback functions that are optional for the user of the behaviour to implement are specified by use of the -optional_callbacks attribute:

@@ -487,10 +479,10 @@ behaviour_info(callbacks) -> generated by the compiler using the -callback attributes.

When the compiler encounters the module attribute - -behaviour(Behaviour). in a module Mod, it will - call Behaviour:behaviour_info(callbacks) and compare the + -behaviour(Behaviour). in a module Mod, it + calls Behaviour:behaviour_info(callbacks) and compares the result with the set of functions actually exported from - Mod, and issue a warning if any callback function is + Mod, and issues a warning if any callback function is missing.

Example:

-- cgit v1.2.3