<?xml version="1.0" encoding="latin1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">

<chapter>
  <header>
    <copyright>
      <year>2003</year><year>2009</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      The contents of this file are subject to the Erlang Public License,
      Version 1.1, (the "License"); you may not use this file except in
      compliance with the License. You should have received a copy of the
      Erlang Public License along with this software. If not, it can be
      retrieved online at http://www.erlang.org/.
    
      Software distributed under the License is distributed on an "AS IS"
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
      the License for the specific language governing rights and limitations
      under the License.
    
    </legalnotice>

    <title>Distributed Erlang</title>
    <prepared></prepared>
    <docno></docno>
    <date></date>
    <rev></rev>
    <file>distributed.xml</file>
  </header>

  <section>
    <title>Distributed Erlang System</title>
    <p>A <em>distributed Erlang system</em> consists of a number of
      Erlang runtime systems communicating with each other. Each such
      runtime system is called a <em>node</em>. Message passing between
      processes at different nodes, as well as links and monitors, are
      transparent when pids are used. Registered names, however, are
      local to each node. This means the node must be specified as well
      when sending messages etc. using registered names.</p>
    <p>The distribution mechanism is implemented using TCP/IP sockets.
      How to implement an alternative carrier is described in <em>ERTS User's Guide</em>.</p>
  </section>

  <section>
    <title>Nodes</title>
    <p>A <em>node</em> is an executing Erlang runtime system which has
      been given a name, using the command line flag <c>-name</c>
      (long names) or <c>-sname</c> (short names).</p>
    <p>The format of the node name is an atom <c>name@host</c> where
      <c>name</c> is the name given by the user and <c>host</c> is
      the full host name if long names are used, or the first part of
      the host name if short names are used. <c>node()</c> returns
      the name of the node. Example:</p>
    <pre>
% <input>erl -name dilbert</input>
(dilbert@uab.ericsson.se)1> <input>node().</input>
'dilbert@uab.ericsson.se'

% <input>erl -sname dilbert</input>
(dilbert@uab)1> <input>node().</input>
dilbert@uab</pre>
    <note>
      <p>A node with a long node name cannot communicate with a node
        with a short node name.</p>
    </note>
  </section>

  <section>
    <title>Node Connections</title>
    <p>The nodes in a distributed Erlang system are loosely connected.
      The first time the name of another node is used, for example if
      <c>spawn(Node,M,F,A)</c> or <c>net_adm:ping(Node)</c> is called,
      a connection attempt to that node will be made.</p>
    <p>Connections are by default transitive. If a node A connects to
      node B, and node B has a connection to node C, then node A will
      also try to connect to node C. This feature can be turned off by
      using the command line flag <c>-connect_all false</c>, see
      <c>erl(1)</c>.</p>
    <p>If a node goes down, all connections to that node are removed.
      Calling <c>erlang:disconnect(Node)</c> will force disconnection
      of a node.</p>
    <p>The list of (visible) nodes currently connected to is returned by
      <c>nodes()</c>.</p>
  </section>

  <section>
    <title>epmd</title>
    <p>The Erlang Port Mapper Daemon <em>epmd</em> is automatically
      started at every host where an Erlang node is started. It is
      responsible for mapping the symbolic node names to machine
      addresses. See <c>epmd(1)</c>.</p>
  </section>

  <section>
    <title>Hidden Nodes</title>
    <p>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&amp;M functionality used to
      inspect the status of a system without disturbing it. For this
      purpose, a <em>hidden node</em> may be used.</p>
    <p>A hidden node is a node started with the command line flag
      <c>-hidden</c>. 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
      <c>nodes()</c>. Instead, <c>nodes(hidden)</c> or
      <c>nodes(connected)</c> must be used. This means, for example,
      that the hidden node will not be added to the set of nodes that
      <c>global</c> is keeping track of.</p>
    <p>This feature was added in Erlang 5.0/OTP R7.</p>
  </section>

  <section>
    <title>C Nodes</title>
    <p>A <em>C node</em> is a C program written to act as a hidden node
      in a distributed Erlang system. The library <em>Erl_Interface</em>
      contains functions for this purpose. Refer to the documentation
      for Erl_Interface and <em>Interoperability Tutorial</em> for more
      information about C nodes.</p>
  </section>

  <section>
    <title>Security</title>
    <p>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 <em>magic cookie</em>, which is an Erlang atom.</p>
    <p>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.</p>
    <p>At start-up, a node has a random atom assigned as its magic
      cookie and the cookie of other nodes is assumed to be
      <c>nocookie</c>. The first action of the Erlang network
      authentication server (<c>auth</c>) is then to read a file named
      <c>$HOME/.erlang.cookie</c>. 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 <c>Cookie</c> is created from the contents of the file and
      the cookie of the local node is set to this using
      <c>erlang:set_cookie(node(), Cookie)</c>. This also makes
      the local node assume that all other nodes have the same cookie
      <c>Cookie</c>.</p>
    <p>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.</p>
    <p>For a node <c>Node1</c> with magic cookie <c>Cookie</c> to be
      able to connect to, or accept a connection from, another node
      <c>Node2</c> with a different cookie <c>DiffCookie</c>,
      the function <c>erlang:set_cookie(Node2, DiffCookie)</c> must
      first be called at <c>Node1</c>. Distributed systems with
      multiple user IDs can be handled in this way.</p>
    <p>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 <c>-connect_all false</c> must be set,
      see <seealso marker="erts:erl">erl(1)</seealso>.</p>
    <p>The magic cookie of the local node is retrieved by calling
      <c>erlang:get_cookie()</c>.</p>
  </section>

  <section>
    <title>Distribution BIFs</title>
    <p>Some useful BIFs for distributed programming, see
      <c>erlang(3)</c> for more information:</p>
    <table>
      <row>
        <cell align="left" valign="middle"><c>erlang:disconnect_node(Node)</c></cell>
        <cell align="left" valign="middle">Forces the disconnection of a node.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>erlang:get_cookie()</c></cell>
        <cell align="left" valign="middle">Returns the magic cookie of the current node.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>is_alive()</c></cell>
        <cell align="left" valign="middle">Returns <c>true</c>if the runtime system is a node and can connect to other nodes, <c>false</c>otherwise.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>monitor_node(Node, true|false)</c></cell>
        <cell align="left" valign="middle">Monitor the status of <c>Node</c>. A message<c>{nodedown, Node}</c>is received if the connection to it is lost.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>node()</c></cell>
        <cell align="left" valign="middle">Returns the name of the current node. Allowed in guards.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>node(Arg)</c></cell>
        <cell align="left" valign="middle">Returns the node where <c>Arg</c>, a pid, reference, or port, is located.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>nodes()</c></cell>
        <cell align="left" valign="middle">Returns a list of all visible nodes this node is connected to.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>nodes(Arg)</c></cell>
        <cell align="left" valign="middle">Depending on <c>Arg</c>, this function  can return a list not only of visible nodes, but also hidden nodes and previously known nodes, etc.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>set_cookie(Node, Cookie)</c></cell>
        <cell align="left" valign="middle">Sets the magic cookie used when connecting to <c>Node</c>. If <c>Node</c>is the current node, <c>Cookie</c>will be used when connecting to all new nodes.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>spawn[_link|_opt](Node, Fun)</c></cell>
        <cell align="left" valign="middle">Creates a process at a remote node.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>spawn[_link|opt](Node, Module, FunctionName, Args)</c></cell>
        <cell align="left" valign="middle">Creates a process at a remote node.</cell>
      </row>
      <tcaption>Distribution BIFs.</tcaption>
    </table>
  </section>

  <section>
    <title>Distribution Command Line Flags</title>
    <p>Examples of command line flags used for distributed programming,
      see <c>erl(1)</c> for more information:</p>
    <table>
      <row>
        <cell align="left" valign="middle"><c>-connect_all false</c></cell>
        <cell align="left" valign="middle">Only explicit connection set-ups will be used.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>-hidden</c></cell>
        <cell align="left" valign="middle">Makes a node into a hidden node.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>-name Name</c></cell>
        <cell align="left" valign="middle">Makes a runtime system into a node, using long node names.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>-setcookie Cookie</c></cell>
        <cell align="left" valign="middle">Same as calling <c>erlang:set_cookie(node(), Cookie)</c>.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>-sname Name</c></cell>
        <cell align="left" valign="middle">Makes a runtime system into a node, using short node names.</cell>
      </row>
      <tcaption>Distribution Command Line Flags.</tcaption>
    </table>
  </section>

  <section>
    <title>Distribution Modules</title>
    <p>Examples of modules useful for distributed programming:</p>
    <p>In Kernel:</p>
    <table>
      <row>
        <cell align="left" valign="middle"><c>global</c></cell>
        <cell align="left" valign="middle">A global name registration facility.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>global_group</c></cell>
        <cell align="left" valign="middle">Grouping nodes to global name registration groups.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>net_adm</c></cell>
        <cell align="left" valign="middle">Various Erlang net administration routines.</cell>
      </row>
      <row>
        <cell align="left" valign="middle"><c>net_kernel</c></cell>
        <cell align="left" valign="middle">Erlang networking kernel.</cell>
      </row>
      <tcaption>Kernel Modules Useful For Distribution.</tcaption>
    </table>
    <p>In STDLIB:</p>
    <table>
      <row>
        <cell align="left" valign="middle"><c>slave</c></cell>
        <cell align="left" valign="middle">Start and control of slave nodes.</cell>
      </row>
      <tcaption>STDLIB Modules Useful For Distribution.</tcaption>
    </table>
  </section>
</chapter>

