RFC: DWhite -- Distributed Whiteboard API

The following is a proposed API for maintaining a distributed copy of
a tree of nodes.  Let me know what you think.

  -- Ken


*** DWhite

DWhite (pronounced like the name Dwight) is an API for synchronizing
trees of nodes.  Although the name is inspired by distributed
whiteboards (a GUI application), DWhite actually supports any type of
tree of data.

DWhite adopts a very simple "Model, View, Controller (MVC)" API.  The
core of DWhite allows a client to synchronize it's local copy of a
"Model" (tree) with the server's version of the same tree.  "Views"
and "Controllers" are applications, logically seperate from the DWhite
core, that can query and manipulate the Model.  Client copies of the
Model can be partially or fully populated.  The logical view of DWhite
and an application on top of it, showing the major flows of data,
looks like this:


           +----------------------------------------+
           |              Application               |
  Client:  +-------------+-------------+------------+
           |    View     |      ^      | Controller |
           +-------------+      |      +------------+
                  ^             |             |
                  |             |             |
  message         /             /             /
   layer          /             /             /
                  |             |             |
                  |             |             v
           +-------------+      |      +------------+
           |    View     |      |      | Controller |
  Server:  +-------------+-------------+------------+
           |                  Model                 |
           +----------------------------------------+

The Model of all applications are trees of nodes.  Nodes may be major
nodes or minor nodes.  Major nodes are the primary nodes of
information in DWhite and may contain many properties, minor subnodes,
and major subnodes.  Major nodes may be copied fully or partially.
Minor nodes may contain many properties, minor subnodes, and major
subnodes, but are always copied in full as part of their containing
major node.  Every major node in DWhite has at least the following
properties:

  DW:Id         The DWhite ID of this node.
  DW:Signature  The DWhite signature of this node.
  DW:Partial    If present, indicates that this is a partial copy.

A DW:Id uniquely identifies a node within one tree of an application
and never changes and is never reused as long as the tree exists.  A
DW:Id will always refer to the same node regardless of where it is
moved in the tree.  A DW:Signature (based on XSignature) records the
state of a node at one point in time and is used to check whether or
not a node has been updated.  DW:Partial indicates whether the node is
fully populated (DW:Partial is false or undefined) or partially
populated (DW:Partial is true).  A partially populated major node
always contains a DW:Id, a DW:Signature, and DW:Partial indicator, and
MAY contain additional properties as defined by an application.

Minor nodes do not have DW:Id's, DW:Signatures's or DW:Partial
indicators, and are always fully populated.

The core DWhite API has only two methods, getNode() and checkNode().
An empty string ("") as a DW:Id always represents the root node of a
tree, it is used as a starting point for building the client copy of
the tree.  The returned root node may have a DW:Id that contains a
real (not "") identifier.  Application View APIs will also have
methods that will return specific (usually partial) nodes within the
tree.

  getNode(NODE)
      getNode() returns a fully populated copy of the node represented
      by the (usually partial) NODE.  All properties and minor
      subnodes will be returned.  Major subnodes will be returned
      partially populated.

  checkNode(NODE)
      checkNode() takes NODE and compares its DW:Signature to the
      server's version of DW:Signature.  If they match, then a partial
      copy of the node is returned (DW:Partial is true).  If they do
      not match, then a full copy of the node is returned, as if
      getNode() had been called (DW:Partial is false or undefined).

Notes:

  * future versions will have methods for setting live queries.

  * need to reference prior art -- possible comparison to WebDAV.
    There's no doubt that this has been done before, just who?

  * authentication is expected in the transport/session layer.

  * distributed relaying of partial and/or full messages.

*** DWhite Chat (DWC)

DWhite Chat is a reference application using DWhite.  DWC nodes
represent a chat room with possibly thousands or millions of small
messages.

The two primary node types in DWC are the Channel node and the Message
node.  A secondary node type, an Index node, is used to partition the
tree into smaller, more easily managed portions.  In the following
description of properties, those properties marked with an asterisk
(*) are copied with partial nodes.

A Channel node contains the following properties:

  *DW:Id        The channel's DWhite identifier.
  *DW:Signature The channel's DWhite signature, will change over time.
  *Name         The channel name of the chat room.
  *Topic        The topic of the chat room.
  *Contents     The contents of the chat room, a list of either Index
                nodes or Message nodes (not mixed).
  *FirstMsgNum  The message number of the first message (always 1).
  *LastMsgNum   The message number of the last message.
  *FirstMsgDate The date and time of the first message.
  *LastMsgDate  The date and time of the last message.

A message node contains the following properties:

  *DW:Id        The message's DWhite identifier.
  *DW:Signature The message's DWhite signature, will never change.
  *From         An identifier (email? URI? UUID?) of the sender.
  *Date         The date when the message entered the tree.
  *MsgNum       The sequence number of the message.
   Body         A string (mixed content?) of up to 500 characters
                containing the body of the message.

An index node contains the following properties:

  *DW:Id        The message's DWhite identifier.
  *DW:Signature The message's DWhite signature, will never change
                after the 50th sub-node is inserted.
  *Contents     The contents of the index, a list of either Index
                nodes or Message nodes (not mixed).
  *FirstMsgNum  The message number of the first message.
  *LastMsgNum   The message number of the last message.
  *FirstMsgDate The date and time of the first message.
  *LastMsgDate  The date and time of the last message.

The Contents of a Channel or Index node will, at any time, only
contain up to 50 sub-nodes.  As soon as the 51st sub-node would have
been created, an Index node is created and the 50 sub-nodes are moved
to the new Index node.  Another Index node will be created and the
51st sub-node will be placed in the new Index node.  The two Index
nodes together replace the Contents of the Channel or Index node that
contained the sub-nodes.  In this manner, a Channel's Contents may
contain 0-N levels of Index nodes, with leaf Index nodes containing
messages.  Index nodes and Message nodes are never mixed within the
Contents of a Channel or Index node; the Contents will contain only
Index nodes or only Message nodes.

DWC has getMessages(), a View method, and postMessage() and
setTopic() Controller methods.  DWC methods are directed towards
the root of the tree.

  getMessages(FIRST, LAST)
      getMessages() will return a partial tree (several layers deep,
      if necessary) containing partial Message nodes for all messages
      between and including FIRST and LAST, and partial nodes for all
      Index nodes and the Channel node that contain them (no Index
      nodes prior to the FIRST or after the LAST message are
      returned).  If FIRST or LAST are negative, then it is counted
      from the end of the message list.  getMessages(-75, -1) will
      return the last 75 messages posted.  getMessages(N, -1) will get
      all the messages from N until the end of the message list.  No
      more than the first 500 partial messages will be returned at one
      time.

  postMessage(MESSAGE)
      postMessage() posts MESSAGE to the Channel.  MESSAGE need only
      contain a From and Body, all other properties will be populated
      by the server.  A full copy of the posted message will be
      returned.  Note, the message number of the returned message may
      be several messages after the last local message.


  setTopic(STRING)
      Sets the Topic of the channel to STRING.

At startup, the client application is expected to use getMessage(-N,
-1) (N between 50-500) to retrieve partial copies of the last N
messages, and then periodically call getMessage(M, -1), where M is the
message number of the last retrieved message plus one.  The
application could also use checkNode() on the Index or Channel nodes.
After calling getMessage(), the application then calls getNode() for
each message to retrieve the fully populated Message node.

Notes

 * future versions will support authentication, authorization, and
   other chat room features.

Received on Thursday, 9 March 2000 09:32:43 UTC