February 26th Thursday 2009 (二月 二十六日 木曜日)

 sort([Pivot|T]) ->
    sort([ X || X <- T, X < Pivot]) ++
    [Pivot] ++
    sort([ X || X <- T, X >= Pivot]);
sort([]) -> [].

Code Replacement

  Erlang supports change of code in a running system. Code replacement is done on module level.

  The code of a module can exist in two variants in a system: current and old. When a module is loaded into the system for the first time, the code
becomes 'current'. If then a new instance of the module is loaded, the code of the previous instance becomes 'old' and the new instance becomes 'current'.

  Both old and current code is valid, and may be evaluated concurrently. Fully qualified function calls always refer to current code. Old code may stil
be evaluated because of processes lingering in the old code.

  If a third instance of the module is loaded, the code server will remove (purge) the old code and any processes lingering in it will be terminated.
Then the third instance becomes 'current' and the previously current code becomes 'old'.

  To change from old code to current code, a process must make a fully qualified function call. Example:

-module(m).
-export([loop/0]).

loop() ->
    receive
        code_switch ->
            m:loop();
        Msg ->
            ...
            loop()
    end.
  To make the process change code, send the message code_switch to it. The process then will make a fully qualified call to m:loop() and change to
current code. Note that m:loop/0 must be exported.

  For code replacement of funs to work, the tuple syntax {Module,FunctionName} must be used to represent the fun.

Code Loading

  The object code must be loaded into the Erlang runtime system. This is handled by the code server.

  The code server loads code according to a code loading strategy which is either interactive (default) or embedded. In interactive mode, code are
searched for in a code path and loaded when first referenced. In embedded mode, code is loaded at start-up according to a boot script.

Errors and Error Handling
  Errors can roughly be divided into four different types:

Compile-time errors
Logical errors
Run-time errors
Generated errors

  A compile-time error, for example a syntax error, should not cause much trouble as it is caught by the compiler.

  A logical error is when a program does not behave as intended, but does not crash. An example could be that nothing happens when a button in a graphical
user interface is clicked.

  A run-time error is when a crash occurs. An example could be when an operator is applied to arguments of the wrong type. The Erlang programming language
has built-in features for handling of run-time errors.

  A run-time error can also be emulated by calling erlang:error(Reason), erlang:error(Reason, Args) (those appeared in Erlang 5.4/OTP-R10), erlang:fault(Reason)
or erlang:fault(Reason, Args) (old equivalents).

  A run-time error is another name for an exception of class error.

  A generated error is when the code itself calls exit/1 or throw/1. Note that emulated run-time errors are not denoted as generated errors here.

  Generated errors are exceptions of classes exit and throw.

  When a run-time error or generated error occurs in Erlang, execution for the process which evaluated the erroneous expression is stopped. This is referred to
as a failure, that execution or evaluation fails, or that the process fails, terminates or exits. Note that a process may terminate/exit for other reasons than a failure.

  A process that terminates will emit an exit signal with an exit reason that says something about which error has occurred. Normally, some information about
the error will be printed to the terminal.


Error Handling

  Erlang has a built-in feature for error handling between processes. Terminating processes will emit exit signals to all linked processes, which may terminate
as well or handle the exit in some way. This feature can be used to build hierarchical program structures where some processes are supervising other processes,
for example restarting them if they terminate abnormally.

Emitting Exit Signals

  When a process terminates, it will terminate with an exit reason as explained in Process Termination above. This exit reason is emitted in an exit signal to all
linked processes.

  A process can also call the function exit(Pid,Reason). This will result in an exit signal with exit reason Reason being emitted to Pid, but does not affect
the calling process.


Receiving Exit Signals

  The default behaviour when a process receives an exit signal with an exit reason other than normal, is to terminate and in turn emit exit signals with the same
exit reason to its linked processes. An exit signal with reason normal is ignored.

  A process can be set to trap exit signals by calling:

process_flag(trap_exit, true)

  When a process is trapping exits, it will not terminate when an exit signal is received. Instead, the signal is transformed into a message {'EXIT',FromPid,Reason}
which is put into the mailbox of the process just like a regular message.

  An exception to the above is if the exit reason is kill, that is if exit(Pid,kill) has been called. This will unconditionally terminate the process, regardless of
if it is trapping exit signals or not.

Monitors

  An alternative to links are monitors. A process Pid1 can create a monitor for Pid2 by calling the BIF erlang:monitor(process, Pid2). The function returns a reference Ref.

  If Pid2 terminates with exit reason Reason, a 'DOWN' message is sent to Pid1:

{'DOWN', Ref, process, Pid2, Reason}

  If Pid2 does not exist, the 'DOWN' message is sent immediately with Reason set to noproc.

  Monitors are unidirectional. Repeated calls to erlang:monitor(process, Pid) will create several, independent monitors and each one will send a 'DOWN' message when Pid
terminates.

  A monitor can be removed by calling erlang:demonitor(Ref).

  It is possible to create monitors for processes with registered names, also at other nodes.

epmd

  The Erlang Port Mapper Daemon epmd is automatically started at every host where an Erlang node is started. It is responsible for mapping the symbolic node names
to machine addresses.

Hidden Nodes

  In a distributed Erlang system, it is sometimes useful to connect to a node without also connecting to all other nodes. An example could be some kind of O&M
functionality used to inspect the status of a system without disturbing it. For this purpose, a hidden node may be used.

  A hidden node is a node started with the command line flag -hidden. Connections between hidden nodes and other nodes are not transitive, they must be set up explicitly.
Also, hidden nodes does not show up in the list of nodes returned by nodes(). Instead, nodes(hidden) or nodes(connected) must be used. This means, for example, that
the hidden node will not be added to the set of nodes that global is keeping track of.

C Nodes

  A C node is a C program written to act as a hidden node in a distributed Erlang system. The library Erl_Interface contains functions for this purpose.

Security

  Authentication determines which nodes are allowed to communicate with each other. In a network of different Erlang nodes, it is built into the system at the
lowest possible level. Each node has its own magic cookie, which is an Erlang atom.

  When a nodes tries to connect to another node, the magic cookies are compared. If they do not match, the connected node rejects the connection.

  At start-up, a node has a random atom assigned as its magic cookie and the cookie of other nodes is assumed to be nocookie. The first action of the Erlang
network authentication server (auth) is then to read a file named $HOME/.erlang.cookie. If the file does not exist, it is created.

  The UNIX permissions mode of the file is set to octal 400 (read-only by user) and its contents are a random string. An atom Cookie is created from the contents
of the file and the cookie of the local node is set to this using erlang:set_cookie(node(), Cookie). This also makes the local node assume that all other nodes
have the same cookie Cookie.

  Thus, groups of users with identical cookie files get Erlang nodes which can communicate freely and without interference from the magic cookie system. Users who
want run nodes on separate file systems must make certain that their cookie files are identical on the different file systems.

  For a node Node1 with magic cookie Cookie to be able to connect to, or accept a connection from, another node Node2 with a different cookie DiffCookie, the function
erlang:set_cookie(Node2, DiffCookie) must first be called at Node1. Distributed systems with multiple user IDs can be handled in this way.

  The default when a connection is established between two nodes, is to immediately connect all other visible nodes as well. This way, there is always a fully
connected network. If there are nodes with different cookies, this method might be inappropriate and the command line flag -connect_all false must be set.

  The magic cookie of the local node is retrieved by calling erlang:get_cookie().

你可能感兴趣的:(February 26th Thursday 2009 (二月 二十六日 木曜日))