This file is indexed.

/usr/share/mozart/doc/system/node46.html is in mozart-doc 1.4.0-8ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

1
2
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>11 General Distributed Programming Support: DP</TITLE><LINK href="ozdoc.css" rel="stylesheet" type="text/css"></HEAD><BODY><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="index.html">- Up -</A></TD><TD><A href="node47.html#chapter.connection">Next &gt;&gt;</A></TD></TR></TABLE><DIV id="chapter.dp"><H1><A name="chapter.dp">11 General Distributed Programming Support: <CODE>DP</CODE></A></H1><P>This module presents the primitive support for distribution provided by the Mozart system. It gives the programmer some control on <EM>how</EM> a language entity is distributed, with a system of <EM>annotations</EM>. It also provides primitives to handle distribution failures. </P><DIV id="section.dp.init"><H2><A name="section.dp.init">11.1 Initializing the Distribution Layer</A></H2><P>The distribution layer of Mozart is dynamically loaded when used. Its load and initialization can be forced with the procedures <CODE>DP<SPAN class="keyword">.</SPAN>init</CODE> and <CODE>DP<SPAN class="keyword">.</SPAN>initWith</CODE>. </P><DL><DT><CODE>init</CODE> <A name="label505"></A></DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{DP<SPAN class="keyword">.</SPAN>init}</CODE></P></BLOCKQUOTE></DD><DD><P>Initializes the distribution layer with parameters determined automatically by the system. The call has no effect if the layer has already been initialized.</P></DD><DT><CODE>initWith</CODE> <A name="label506"></A></DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{DP<SPAN class="keyword">.</SPAN>initWith&nbsp;</CODE><CODE>+<I>Spec</I></CODE><CODE>}</CODE></P></BLOCKQUOTE></DD><DD><P>Initializes the distribution layer according to <CODE><I>Spec</I></CODE>. It has no effect if the layer had already been initialized. The value <CODE><I>Spec</I></CODE> is a record of the type </P><BLOCKQUOTE class="code"><CODE>init(ip:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</CODE><CODE><I>IP</I></CODE><CODE>&nbsp;<SPAN class="keyword">&lt;=</SPAN>&nbsp;best<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</CODE><CODE><I>PN</I></CODE><CODE>&nbsp;<SPAN class="keyword">&lt;=</SPAN>&nbsp;<SPAN class="string">'from'</SPAN>(9000)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firewall:&nbsp;</CODE><CODE><I>FW</I></CODE><CODE>&nbsp;<SPAN class="keyword">&lt;=</SPAN>&nbsp;<SPAN class="keyword">false</SPAN>)</CODE></BLOCKQUOTE><P> All entries in record <CODE><I>Spec</I></CODE> are optional. The default values shown above are used if not given. The fields have the following meaning. </P><UL><LI><P><CODE><I>IP</I></CODE> defines the IP address that the Mozart site should expose as its home address. It is either a string like <CODE><SPAN class="string">&quot;193.10.66.192&quot;</SPAN></CODE> or the atom <CODE>best</CODE>. With the latter, the system will map the host name of the computer to an IP address. The IP address should only be set if the operating system returns a faulty address for some reason.</P></LI><LI><P><CODE><I>PN</I></CODE> sets the port number that should be used for listening to incoming connection attempts. If <CODE><I>PN</I></CODE> has the form <CODE>exact(</CODE><CODE><I>N</I></CODE><CODE>)</CODE>, the distribution layer will try to obtain the port number <CODE><I>N</I></CODE>. If <CODE><I>PN</I></CODE> has the form <CODE><SPAN class="string">'from'</SPAN>(</CODE><CODE><I>N</I></CODE><CODE>)</CODE>, the system will try to obtain the port number <CODE><I>N</I></CODE>. If that port is unavailable, port <CODE><I>N</I></CODE>+1 will be tried, then <CODE><I>N</I></CODE>+2, and so on, until a port number is granted by the operating system. If <CODE><I>PN</I></CODE> is <CODE>free</CODE>, then the distribution layer will pick the first port number granted by the operating system.</P></LI><LI><P><CODE><I>FW</I></CODE> is a boolean value that indicates if this site's host is behind a firewall. If it has value <CODE><SPAN class="keyword">true</SPAN></CODE>, connection attempts will be tried from inside to outside the firewall.</P></LI></UL><P> </P></DD></DL><P> </P><P>The record <CODE><I>Spec</I></CODE> given to <CODE>DP<SPAN class="keyword">.</SPAN>initWith</CODE> can also be set as property <CODE><SPAN class="string">'dp.listenerParams'</SPAN></CODE> in module <CODE>Property</CODE>. Setting the property does not force the distribution layer to be initialized. The call <CODE>{DP<SPAN class="keyword">.</SPAN>initWith&nbsp;</CODE><CODE><I>Spec</I></CODE><CODE>}</CODE> is equivalent to </P><BLOCKQUOTE class="code"><CODE>{Property<SPAN class="keyword">.</SPAN>put&nbsp;<SPAN class="string">'dp.listenerParams'</SPAN>&nbsp;<BR>&nbsp;{Adjoin&nbsp;{Property<SPAN class="keyword">.</SPAN>get&nbsp;<SPAN class="string">'dp.listenerParams'</SPAN>}&nbsp;</CODE><CODE><I>Spec</I></CODE><CODE>}<BR>{DP<SPAN class="keyword">.</SPAN>init}</CODE></BLOCKQUOTE><P> </P></DIV><DIV id="section.dp.annotations"><H2><A name="section.dp.annotations">11.2 Distribution Annotations</A></H2><P>Since Mozart 1.4.0, the distribution support provides more choices on how an entity is distributed. The programmer can choose between several protocols for the management of an entity's state, and its distributed memory management. The choice is specified by attaching an <EM>annotation</EM> to the entity. Once an entity is distributed, the system determines its distribution parameters (state protocol and memory management) by looking up the entity's annotation. If some parameters are missing in the annotation, the system uses default values for the corresponding parameters. Default values are discussed below (<A href="node46.html#section.dp.annotations.defaults">Section&nbsp;11.2.3</A>). </P><P>An annotation value is either an atom or a list of atoms. Valid values are given below. It may specify a protocol (like <CODE>stationary</CODE>), a memory management scheme (like <CODE>[persistent]</CODE>), or both (like <CODE>[stationary&nbsp;persistent]</CODE>). The annotation is <EM>complete</EM> if both a protocol and a memory management scheme are given, otherwise it is <EM>partial</EM>. </P><H3><A name="label507">11.2.1 Annotating Entities</A></H3><P>The following two operations handle entity operations. The annotation mechanism is incremental: one can annotate an entity several times, the resulting annotation for the entity being the conjunction of the given annotations. </P><DL><DT><CODE>annotate</CODE> <A name="label508"></A></DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{DP<SPAN class="keyword">.</SPAN>annotate&nbsp;</CODE><CODE><I>X</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>Annot</I></CODE><CODE>}</CODE></P></BLOCKQUOTE></DD><DD><P>Annotate entity <CODE><I>X</I></CODE> with the given annotation. The annotation must be consistent and valid for the given entity. An exception is raised otherwise.</P></DD><DT><CODE>getAnnotation</CODE> <A name="label509"></A></DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{DP<SPAN class="keyword">.</SPAN>getAnnotation&nbsp;</CODE><CODE><I>X</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>Annot</I></CODE><CODE>}</CODE></P></BLOCKQUOTE></DD><DD><P>Return the annotation <CODE><I>Annot</I></CODE> of entity <CODE><I>X</I></CODE> as a list of atomic annotations. The list is empty if the entity has not been annotated yet.</P></DD></DL><P> </P><H3><A name="label510">11.2.2 Annotation Values</A></H3><P>The following table lists the valid protocol annotations, and to which kind of entity they can be applied. </P><TABLE align="center" bgcolor="#f0f0e0" id="table.annotations.protocols"><TR valign="top"><TH><P>Value</P></TH><TH><P>Entity type</P></TH><TH><P>Description</P></TH></TR><TR valign="top"><TD><P><CODE>sited</CODE></P></TD><TD><P>mutable, immutable</P></TD><TD><P>Makes an entity sited (no distribution support). The entity will appear outside its home site as an <EM>unusable</EM>.</P></TD></TR><TR valign="top"><TD><P><CODE>stationary</CODE></P></TD><TD><P>mutable, immutable</P></TD><TD><P>The entity's state remains on its home site.</P></TD></TR><TR valign="top"><TD><P><CODE>migratory</CODE>, <CODE>pilgrim</CODE></P></TD><TD><P>mutable</P></TD><TD><P>The state of the entity is freely mobile; it migrates on sites where entity operations must be performed. With the <CODE>pilgrim</CODE> protocol, the state continuously moves between the sites that regularly perform operations on the entity.</P></TD></TR><TR valign="top"><TD><P><CODE>replicated</CODE></P></TD><TD><P>mutable</P></TD><TD><P>The entity's state is replicated on all sites referring to the entity. Read operations are performed locally, while write operations atomically update all replicas with a two-phase commit-like protocol.</P></TD></TR><TR valign="top"><TD><P><CODE>immediate</CODE></P></TD><TD><P>immutable</P></TD><TD><P>The complete representation of the entity is sent together with its reference.</P></TD></TR><TR valign="top"><TD><P><CODE>eager</CODE>, <CODE>lazy</CODE></P></TD><TD><P>immutable</P></TD><TD><P>With those protocols, the representation of the entity is sent at most once to a site. The <CODE>eager</CODE> protocol copies the entity as soon as possible, while the <CODE>lazy</CODE> protocol delays the copy until it is required on the site.</P></TD></TR><TR valign="top"><TD><P><CODE>variable</CODE>, <CODE>reply</CODE></P></TD><TD><P>transient</P></TD><TD><P>For variables and read-only futures. The <CODE>reply</CODE> protocol is an optimization of the <CODE>variable</CODE> protocol for the case where two sites share the variable, and the variable is bound by the remote site. That protocol should not be used with read-only futures.</P></TD></TR></TABLE><P> </P><P>The table below lists annotations for distributed memory management. </P><TABLE align="center" bgcolor="#f0f0e0" id="table.annotations.memory"><TR valign="top"><TH><P>Annotation</P></TH><TH><P>Description</P></TH></TR><TR valign="top"><TD><P><CODE>persistent</CODE></P></TD><TD><P>The entity remains alive forever.</P></TD></TR><TR valign="top"><TD><P><CODE>credit</CODE></P></TD><TD><P>All references to the entity (on sites or in network messages) embed a certain amount of <EM>credits</EM>. The total amount of credits remains constant, and remote sites can exchange references without notifying the home site (they put a part of their own credits with the reference they exchange). When all credits are sent back to the home site (by the remote sites' respective garbage collectors), that site is able to remove the entity from its own memory.</P></TD></TR><TR valign="top"><TD><P><CODE>lease</CODE></P></TD><TD><P>All sites referring to an entity periodically notify its home site of their presence. When the home site has not had any notification for a long time, it considers that the entity has no more remote references, and makes the entity local to its site. This scheme allows to collect memory in the case where remote references are lost with site failures. It is not guaranteed correct, though.</P></TD></TR></TABLE><P> </P><P><EM>Note.</EM> The annotations <CODE>credit</CODE> and <CODE>lease</CODE> can be combined in a single annotation as <CODE>[credit&nbsp;lease]</CODE>. In that case, the home site will localize the entity as soon as one of both schemes declares it as local. The <CODE>credit</CODE> scheme will react quicker in case of no failure, while the <CODE>lease</CODE> scheme will still allow garbage collection in case some credits are lost in a site failure. </P><DIV id="section.dp.annotations.defaults"><H3><A name="section.dp.annotations.defaults">11.2.3 Default Annotations</A></H3><P>The system defines default annotations for all types of entities. Those default annotations are set as system properties in the module <CODE>Property</CODE> (<A href="node61.html#section.property.dp">Section&nbsp;``Distribution: <CODE>dp</CODE>''</A>). The default annotation set for a given type must be complete and adequate for that type of entity. For instance, the statement below configures objects to be stationary by default, and classes to be copied lazily. Note that default annotations are used for entities created on the current site only. </P><BLOCKQUOTE class="code"><CODE>{Property<SPAN class="keyword">.</SPAN>put&nbsp;<SPAN class="string">'dp.annotation.object'</SPAN>&nbsp;[stationary&nbsp;credit]}<BR>{Property<SPAN class="keyword">.</SPAN>put&nbsp;<SPAN class="string">'dp.annotation.class'</SPAN>&nbsp;[lazy&nbsp;credit]}</CODE></BLOCKQUOTE><P> </P></DIV></DIV><DIV id="section.dp.fault"><H2><A name="section.dp.fault">11.3 Fault Handling</A></H2><P>At global scale, there is only one kind of entity failure in Mozart: the entity permanently cease to function. For instance, if the home site of an entity crashes, and that site was necessary for the entity to function properly, the entity itself fails permanently. The failure of an entity can also be provoked on purpose by the programmer. This may simplify some fault handling algorithms, because it makes sure the entity is failed permanently. </P><P>At local scale, every site can observe entity failures. It may observe the global failure of an entity, but it may also observe unknown failures. Bad network communication can prevent an operation to perform on an entity. The failure may be temporary, and go away once the network communication is reestablished. But it may also hide a real permanent failure. The possible failures observed at a site are </P><UL><LI><P><CODE>ok</CODE>: the entity seems to be working properly.</P></LI><LI><P><CODE>tempFail</CODE>: the entity is unusable on this site because of an unknown failure.</P></LI><LI><P><CODE>localFail</CODE>: the entity is permanently unusable on this site, but the failure may not be global. This failure is provoked by the operation <CODE>break</CODE> below.</P></LI><LI><P><CODE>permFail</CODE>: the entity is failed globally.</P></LI></UL><P> </P><P>Valid fault state transitions are shown in <A href="node46.html#fig.faultstates">Figure&nbsp;11.1</A>. One can see that from fault states <CODE>localFail</CODE> and <CODE>permFail</CODE>, one can never go back to state <CODE>ok</CODE> again (see <A href="node46.html#section.dp.limitations">Section&nbsp;11.5</A>, though). </P><P></P><DIV id="fig.faultstates"><HR><P><A name="fig.faultstates"></A></P><DIV align="center"><IMG alt="" src="faultstates.png"></DIV><P class="caption"><STRONG>Figure&nbsp;11.1:</STRONG> State diagram with valid fault state transitions</P><HR></DIV><P> </P><P>A synchronous operation on a failed entity simply <EM>blocks</EM>. If the failure is transient, then the operation naturally resumes once the failure goes away. If the failure is permanent, then the operation blocks forever. Contrary to versions of Mozart prior to 1.4.0, an operation on failed entity never raises an exception because of the failure. </P><P>An asynchronous operation on a failed entity returns immediately as usual. If the failure is temporary, then the operation will eventually perform its effect. In the case of a permanent failure, the effect will never occur. </P><H3><A name="label511">11.3.1 Entity Fault Stream</A></H3><P>Every site maintains a <EM>local fault state</EM> for every entity, and that fault state is available to the programmer. In order to allow the programmer to react to fault state <EM>transitions</EM>, the site provides a <EM>fault stream</EM> for every entity. The fault stream of an entity is extended automatically with that entity's local fault state every time it changes. </P><DL><DT><CODE>getFaultStream</CODE> <A name="label512"></A></DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{DP<SPAN class="keyword">.</SPAN>getFaultStream&nbsp;</CODE><CODE><I>X</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>FS</I></CODE><CODE>}</CODE></P></BLOCKQUOTE></DD><DD><P>Return the current tail of the fault stream of entity <CODE><I>X</I></CODE>, prefixed with the current fault state of <CODE><I>X</I></CODE>. Therefore, the current fault state of <CODE><I>X</I></CODE> is given by <CODE>{DP<SPAN class="keyword">.</SPAN>getFaultStream&nbsp;</CODE><CODE><I>X</I></CODE><CODE>}<SPAN class="keyword">.</SPAN>1</CODE>.</P></DD></DL><P> Once an entity is removed from memory by the local garbage collector, its fault stream is automatically <EM>closed</EM>, i.e., its tail is bound to <CODE>nil</CODE>. This gives a simple way for a fault handler to detect that the entity it watches is no longer in use. This finalization mechanism is triggered at the same time as the <EM>post-mortem finalization</EM> of the entity (<A href="node79.html#chapter.finalize">Chapter&nbsp;26</A>). </P><H3><A name="label513">11.3.2 Kill and Break</A></H3><P>Entity failure can be provoked explicitly by the programmer. It can apply either globally, or locally. These operations can be useful in order to guarantee that an entity will no longer be used. </P><DL><DT><CODE>kill</CODE> <A name="label514"></A></DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{DP<SPAN class="keyword">.</SPAN>kill&nbsp;</CODE><CODE><I>X</I></CODE><CODE>}</CODE></P></BLOCKQUOTE></DD><DD><P>Eventually make entity <CODE><I>X</I></CODE> fail permanently, if possible. This operation is asynchronous, and is not guaranteed to proceed. Its success is confirmed once the fault state <CODE>permFail</CODE> appears on the entity's fault stream.</P></DD><DT><CODE>break</CODE> <A name="label515"></A></DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{DP<SPAN class="keyword">.</SPAN>break&nbsp;</CODE><CODE><I>X</I></CODE><CODE>}</CODE></P></BLOCKQUOTE></DD><DD><P>This operation makes the entity <CODE><I>X</I></CODE> fail on the current site, if possible. The operation proceeds immediately, since only the current site is involved. It has no effect on other sites.</P></DD></DL><P> </P></DIV><DIV id="section.dp.variables"><H2><A name="section.dp.variables">11.4 Special Case: Variables</A></H2><P>Variables are a bit trickier to manipulate because of their transient nature. One may experience a race condition if a variable is bound and concurrently annotated: the annotation may fail. In order to avoid such a race condition, one should perform the annotation on a fresh variable, then bind the latter to the target variable. If the target variable is not annotated yet, the annotation is automatically transferred to it. </P><BLOCKQUOTE class="code"><CODE><SPAN class="keyword">local</SPAN>&nbsp;Y&nbsp;<SPAN class="keyword">in</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;{DP<SPAN class="keyword">.</SPAN>annotate&nbsp;Y&nbsp;reply}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">annotate&nbsp;Y<BR></SPAN>&nbsp;&nbsp;&nbsp;X=Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">transfer&nbsp;annotation&nbsp;to&nbsp;X&nbsp;if&nbsp;possible<BR></SPAN><SPAN class="keyword">end</SPAN></CODE></BLOCKQUOTE><P> A similar rule applies for the fault stream of a variable. If a variable is bound to another variable, their fault streams are <EM>merged</EM>: their tails are bound to each other, possibly with an intermediate fault state if they have different fault states. </P><BLOCKQUOTE class="code"><CODE><SPAN class="keyword">local</SPAN>&nbsp;Y&nbsp;<SPAN class="keyword">in</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;FS={DP<SPAN class="keyword">.</SPAN>getFaultStream&nbsp;Y}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">take&nbsp;fault&nbsp;stream&nbsp;of&nbsp;Y<BR></SPAN>&nbsp;&nbsp;&nbsp;X=Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">FS&nbsp;is&nbsp;now&nbsp;the&nbsp;fault&nbsp;stream&nbsp;of&nbsp;X,&nbsp;too<BR></SPAN><SPAN class="keyword">end</SPAN></CODE></BLOCKQUOTE><P> Note that if the variable is bound to a value, its fault stream is closed. </P></DIV><DIV id="section.dp.limitations"><H2><A name="section.dp.limitations">11.5 Limitations</A></H2><P></P><UL><LI><P>If an entity <CODE><I>X</I></CODE> has fault state <CODE>localFail</CODE> on a site <CODE><I>S</I></CODE>, then no operation on <CODE><I>X</I></CODE> will ever succeed on <CODE><I>S</I></CODE>. This property is guaranteed, but only as long as <CODE><I>X</I></CODE> remains in memory of <CODE><I>S</I></CODE>. Indeed, this state has no effect on other sites, and by default only <CODE><I>S</I></CODE> knows that fault state for <CODE><I>X</I></CODE>. If <CODE><I>X</I></CODE> is removed by the garbage collector of <CODE><I>S</I></CODE>, then its fault state on <CODE><I>S</I></CODE> vanishes. In that case, if <CODE><I>X</I></CODE> is reintroduced later to <CODE><I>S</I></CODE>, it might be considered in state <CODE>ok</CODE> again.</P></LI><LI><P>Since version 1.4.0, the fault state <CODE>tempFail</CODE> is triggered based on an adaptive timeout. The system monitors its site connections, and determines an average round-trip time and deviation for each connection. Because the mechanism is adaptive, it requires some time to find appropriate values. Therefore the failure detection can sometimes appear too sensitive, and sometimes a bit sloppy.</P></LI></UL><P> </P></DIV></DIV><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="index.html">- Up -</A></TD><TD><A href="node47.html#chapter.connection">Next &gt;&gt;</A></TD></TR></TABLE><HR><ADDRESS><A href="http://www.ps.uni-sb.de/~duchier/">Denys&nbsp;Duchier</A>, <A href="http://www.ps.uni-sb.de/~kornstae/">Leif&nbsp;Kornstaedt</A>, <A href="http://www.ps.uni-sb.de/~homik/">Martin&nbsp;Homik</A>, <A href="http://www.ps.uni-sb.de/~tmueller/">Tobias&nbsp;Müller</A>, <A href="http://www.ps.uni-sb.de/~schulte/">Christian&nbsp;Schulte</A> and&nbsp;<A href="http://www.info.ucl.ac.be/~pvr">Peter&nbsp;Van Roy</A><BR><SPAN class="version">Version 1.4.0 (20110908185330)</SPAN></ADDRESS></BODY></HTML>