DSync / Behaviour Theory

(C) 2005-06-03 by Oliver Seidel 


At university I built a 1200 line program named "filescrc.c".  It
performed the same function as "app_dsync" in that it attempted to
keep a set of directories in sync via the generation of transport
files.  Within that utility, I hard-coded the following commands:

    fc_sync=0,  // export until synchronised
    fc_ignonce, // ignore this file once
    fc_ignore,  // ignore this file
    fc_everywhr,// Export from everywhere
    fc_newntc,  // newly noticed
    fc_askcmd,  // ask for command
    fc_export,  // export file to elsewhere
    fc_exptwice,// export file to elsewhere and then again
    fc_delete,  // delete file from everywhere
    fc_telldel, // notify user that this is being removed from db
    fc_really_export,  // really export file to elsewhere
    fc_always,  // always export, no matter whether changed
    fc_count,   // last official one
    fc_sys_0,   // system 0
    fc_sys_1,   // system 1
    fc_sys_2,   // ...

These commands represented inputs that I as the user could make while
generating the transport file.  Since "app_dsync" is the successor to
this utility, it needs to build upon the previous experience and go
about the whole procedure in a more structured manner.

Layers of abstraction:

Unfortunately, the above list of options is a mix of commands for
different purposes.  The purposes can be divided into the following

1) for each particular file within the transport container, the user
   does wish to indicate a particular command.  The possible commands
   at the time of writing are "delete", "import", "ignore",
   "rename_both".  They refer to what they do to the copy brought by
   the transport file and the local copy.

2) during a single run of the program a user may need to classify a
   very large number of files with the appropriate action command, as
   described in 1) above.  To ease this task, the user interface
   offers to change the display order by various sorting criteria and
   allows for contiguous groups of files to be selected from that sort

3) finally does the user call upon the system repeatedly over the
   course of time and acts on particular files in a repeatable manner.
   This is where the Behaviour system comes into play.  A Behaviour
   can be associated with a particular file, a directory where the
   Behaviour applies to all its siblings, or even as the default
   operation of a whole Remote_Tab (a Remote_Tab is a UI component of
   the DSync application).  More general Behaviour enclosures are only
   called upon for remote/local-pairs not yet assigned a command by a
   more concrete rule or even the user herself.

Operation of a Behaviour:

A Behaviour is simply a NAME, followed by an ordered list of rules.
Each rule supplies a command in case of success and covers a subset of
the whole parameter space.  The parameter space draws upon the
metadata for the remote file and the local file.  Some dimensions of
the parameter space may be (if I get 'round to implementing them):

    local copy { added, deleted, modified }

    remote copy { added, deleted, modified }

    remote_size { bigger, smaller, same }

    remote_fresher { yes, no, maybe }
       -- the joys of distributed computation: think of clock skew

    remote_security_tighter { yes, no, different }
       -- the joys of cross platform computation: ACLs and Capabilities

For the sake of simplicity, assume I have only implemented the first
two and I wish to describe a Behaviour named "remote_is_master":

			local	local	local
			added	deleted	modified
	remote		import	import	import

	remote		delete	delete	delete

	remote		import	import	import

The Behaviour specification for this description could be defined as

	remote_is_master=import if different and remote_added/modified;
				delete if different and remote_deleted

As you can easily see, two rules are used to indicate two different
commands (import and delete, as shown here) for two different
subspaces of the complete parameter space (top and bottom third for
the first rule; the mid-section for the second rule).  If more
parameters are considered, the complete parameter space will be higher
dimensional (and thus difficult to depict here, since even the
venerable Lotus Improv on a NeXT cube took some time to get used to).

Please go on to note that my example above covers the complete
parameter space, but this is hardly a necessity.  If a particular
Behaviour omits bits of the lattice, more general Behaviours (like
from an enclosing directory, or even frmo the whole Remote_Tab) still
has a chance to supply the necessary command.

The BNF of a Behaviour entry is rather simple (while ugly), if you are
willing to resolve  through a reference to the RegEx contained
in net.os10000.bldsys.lib_dirtree.Behaviour.Rule.r_pattern:

 := ( ";" )*  ( ";" (  )? )*