for name, e in sorted((k, e) for k, e in vars(self).iteritems()
if isinstance(e, self.Enum))]
other = []
other = []
for k in (
for k in (
'INVALID_TID',
'INVALID_TID',
...
@@ -177,15 +616,19 @@ class Protocol(object):
...
@@ -177,15 +616,19 @@ class Protocol(object):
return """
return """
<detailsopen="">
<detailsopen="">
<p>The following table lists the %s different types of messages that can be exchanged.
<p>The <em>message code</em> encodes the type of the message.
The following table lists the %s different types that can be exchanged.
%s are them are requests with response packets.
%s are them are requests with response packets.
1 is a generic response packet for error handling.
1 is a generic response packet for error handling.
The remaining %s are notification packets.</p>
The remaining %s are notification packets.</p>
<p>The <em>code (#)</em> of a response packet is the same as the corresponding request one, with the highest order bit set. Using Python language, it translates as follows:</p>
<p>The <em>code (#)</em> of a response packet is the same as the corresponding request one, with the highest order bit set. Using Python language, it translates as follows:</p>
<pre>response_code = request_code | 0x%x</pre>
<pre>response_code = request_code | 0x%x</pre>
<p>The <em>format</em> columns refer to item types,
<p><em>Message IDs</em> are used to identify response packets: each node sends a request with a unique value and the peer replies using the same id as the request. Notification packets normally follow the same rule as request packets, for debugging purpose. In some complex cases where replying is done with several notification packets followed by a response one (e.g. replication), the notification packets must have the same id as the response.</p>
which are described in the next table with Python literals, and in particular
<pstyle="margin-left: 2em;"><strong>Notice to implementers</strong>:</p>
<li>A 32-bit counter can be used for <em>Message IDs</em>, 0 being the value of the first sent message, and the value is reset to 0 after 0xffffffff.</li>
<li>On error, the implementer is free to answer with a <em>Error</em> packet before aborting the connection, so that the requesting node logs debugging information. We will only document other uses of <em>Error</em>.</li>
</ul>
</details>
</details>
<detailsopen="">
<detailsopen="">
...
@@ -198,52 +641,23 @@ which are described in the next table with Python literals, and in particular
...
@@ -198,52 +641,23 @@ which are described in the next table with Python literals, and in particular
<th>Description</th>
<th>Description</th>
<th>Workflow</th>
<th>Workflow</th>
<th>Nodes</th>
<th>Nodes</th>
<!--
<th>Format</th>
<th>Format</th>
<th>Answer Format</th>
<th>Answer Format</th>
-->
</tr>
</tr>
%s</table>
%s</table>
</div>
</div>
</details>
</details>
<detailsopen="">
<summary>Item Types</summary>
<table>
<tr>
<th>Type</th>
<th>Encoding</th>
<th>Null (e.g. Python's None)</th>
</tr>
<tr>
<td>(...)</td>
<td>each item is encoded one after the other</td>
<td>-</td>
</tr>
<tr>
<td>[...]</td>
<td>count(%s), (...)</td>
<td>-</td>
</tr>
<tr>
<td>{keys: values}</td>
<td>[(key, value)]</td>
<td>-</td>
</tr>
<tr>
<td>(...)?</td>
<td><span>'\\1'</span>, (...)</td>
<td>'\\0'</td>
</tr>
%s</table>
<p><strong>Note:</strong> There's no UUID anymore in NEO and PUUID must renamed into PNID.</p>
<pstyle="margin-left: 2em;"><strong>Naming choice</strong>: For cell states, node states and node types, names are chosen to have unambiguous initials, which is useful to produce shorter logs or have a more compact user interface. This explains for example why <em>RUNNING</em> was preferred over <em>UP</em>.</p>
<p>Enum values are serialized using <em>Extension</em> mechanism: <em>type</em> is the number of the Enum type (as listed above), <em>data</em> is MessagePack serialization of the Enum value (i.e. a positive integer). For exemple, <em>NodeStates.RUNNING</em> is encoded as <tt>\\xd4\\x03\\x02</tt>.</p>
<p><strong>Naming choice</strong>: For cell states, node states and node types, names are chosen to have unambiguous initials, which is useful to produce shorter logs or have a more compact user interface. This explains for example why <em>RUNNING</em> was preferred over <em>UP</em>.</p>
</details>
</details>
<detailsopen="">
<detailsopen="">
...
@@ -251,7 +665,7 @@ which are described in the next table with Python literals, and in particular
...
@@ -251,7 +665,7 @@ which are described in the next table with Python literals, and in particular
<table>
<table>
%s</table>
%s</table>
<p>MAX_TID could be bigger but in the Python implementation, TIDs are stored as integers and some storage backend may have no support for values above 2⁶³-1 (e.g. SQLite).</p>
<p>MAX_TID could be bigger but in the Python implementation, TIDs are stored as integers and some storage backend may have no support for values above 2⁶³-1 (e.g. SQLite).</p>
<p>Node ID namespaces are required to prevent conflicts when the master generates new ids before it knows those of existing storage nodes. The high-order byte of node ids is one the following values:</p>
<p>Node IDs are 32-bit integers. NID namespaces are required to prevent conflicts when the master generates new ids before it knows those of existing storage nodes. The high-order byte of node ids is one the following values:</p>
<table>
<table>
<tr><td>Storage</td><td>0x00</td></tr>
<tr><td>Storage</td><td>0x00</td></tr>
<tr><td>Master</td><td>-0x10</td></tr>
<tr><td>Master</td><td>-0x10</td></tr>
...
@@ -262,10 +676,12 @@ which are described in the next table with Python literals, and in particular
...
@@ -262,10 +676,12 @@ which are described in the next table with Python literals, and in particular