@need 3200

@node Driving Process Automation with arch Notifiers
@chapter Driving Process Automation with arch Notifiers

@geindex notify



@strong{Active Development Warning:} The features described in this chapter
are likely to change in incompatible ways before the @code{1}.0 release of
@code{arch}.


In some circumstances, it is very useful to trigger actions upon the
detection of changes to an archive.  For example, you might want to
send an email notification whenever new revisions are checked in.


The command @code{notify} provides this capability:

@example
@group
        % larch notify NOTIFICATION-DIR
@end group
@group
@end group
@end example

That command reads configuration files found in @code{NOTIFICATION-DIR}.
Those configuration files explain what parts of which repositories to
monitor, and what actions to take upon changes.  When changes are
detected, @code{notify} invokes actions.


This chapter explains @code{notify} in general.  It documents the format of
a @code{NOTIFICATION-DIR} and the configuration files.  It explains what
@code{notify} does.  

@need 3200

@section The Four notify Configuration Files

|=rules.archives|
|=rules.categories|
|=rules.branches|
|=rules.versions|


@code{notify} is controlled by four configuration files, found at the root
of a @code{NOTIFICATION-DIR}.  These are:

@example
@group

@end group
@group
        =rules.archives
                Specifies actions to take whenever new categories
                are added to specific archives.
@end group
@group

@end group
@group
        =rules.categories
                Specifies actions to take whenever new branches
                are added to specific categories.
@end group
@group

@end group
@group
        =rules.branches
                Specifies actions to take whenever new versions
                are added to specific branches.
@end group
@group

@end group
@group
        =rules.versions
                Specifies actions to take whenever new revisions
                are added to specific versions.
@end group
@group

@end group
@end example

Within these files, blank lines are permitted and comments begin with
'#' and continue to the end of line. 


The file @code{=rules.versions} contains lines with the format:

@example
@group
        VERSION         ACTION
@end group
@group
@end group
@end example

@noindent
where @code{VERSION} is a fully-qualified version name, and action a string
(with no whitespace) of the form:

@example
@group
        COMMAND:THUNK
@end group
@group
@end group
@end example

Whenever new revisions are detected in @code{VERSION}, @code{notify} invokes:

@example
@group
        larch COMMAND THUNK RVN ...
@end group
@group
@end group
@end example

@noindent
where @code{COMMAND} and @code{THUNK} are from the configuration file, and the
trailing @code{RVN} arguments are a list of fully qualified revision names
of newly detected revisions.


The file @code{=rules.branches} is similar.  It contains lines of the form:

@example
@group
        BRANCH COMMAND:THUNK VERSION-ACTION
@end group
@group
@end group
@end example

Whenever new versions are created in @code{BRANCH}, @code{notify} takes two
actions.  First, it invokes:

@example
@group
        larch COMMAND THUNK VSN ...
@end group
@group
@end group
@end example

Second, it adds new rules to @code{=rules.versions} of the form:

@example
@group
        VSN     VERSION-ACTION
@end group
@group
@end group
@end example

The files @code{=rules.categories} and @code{=rules.archives} are similar.  The
former contains lines of the form:

@example
@group
        CATEGORY COMMAND:THUNK BRANCH-ACTION VERSION-ACTION
@end group
@group
@end group
@end example

@noindent
and the latter lines of the form:

@example
@group
        ARCHIVE COMMAND:THUNK CATEGORY-ACT BRANCH-ACT VERSION-ACT
@end group
@group
@end group
@end example

In addition to the configuration files, @code{notify} maintains its private
state in @code{NOTIFY-DIR}.  In particular, it keeps track of what
notifications have already been sent, in order to try to avoid sending
redundant notifications.




@need 3200

@section Notifiers for Everything in a Repository 

Configuring notifiers for every category, branch, and version in an
archive is quite simple: you only need to write the @code{=rules.archives}
file -- other configuration files will be automatically generated from
that.


The initial @code{=rules.archives} file should contain lines of the form:

@example
@group
        ARCHIVE COMMAND:THUNK CATEGORY-ACT BRANCH-ACT VERSION-ACT
@end group
@group
@end group
@end example

@noindent
for each set of actions you want to trigger.  After creating the config
file, run @code{notify} in that directory.  The first run will detect all
categories in the repository, invoke @code{COMMAND} for those, and create a
@code{rules.categories} file with lines:

@example
@group
        CATEGORY CATEGORY-ACT BRANCH-ACT VERSION-ACT
@end group
@group
@end group
@end example

Then @code{notify} will read that config file, detect all the branches in
the repository, invoke @code{CATEGORY-ACT}, and create @code{=rules.branches}.


Finally, @code{=rules.versions} will be automatically created in a similar
way.


Whenever a new category, branch, or version is added to an archive,
the rules files will be automatically updated to reflect the addition
(when @code{notify} is run, of course).




@need 3200

@section Mailing Out Notices

These commands can be used in notifier rules to send mail announcing
new additions to an archive:

@example
@group
        mail-new-categories
        mail-new-branches
        mail-new-versions
        mail-new-revisions
@end group
@group
@end group
@end example

This command, if invoked for new revisions, can be used to add those
revisions to the revision library registered with
@code{my-revision-library}:

@example
@group
        notify-library
@end group
@group
@end group
@end example

Finally, the @code{noop} command can be used as a place-holder for notifier
events where no actions is needed.


Putting those commands together, you can create an @code{=rules.archives}
file that sends out announcements and updates a revision library for
an archive (long lines wrapped for legibility):


/*insert

@example
@group
        lord@@emf.net--2003              mail-new-categories:lord \
                                        mail-new-branches:lord \
                                        mail-new-versions:lord \
                                        mail-new-revisions:lord
@end group
@group
@end group
@end example
@example
@group
        lord@@emf.net--2003              noop:notify-library:lord \
                                        noop:notify-library:lord \
                                        noop:notify-library:lord \
                                        notify-library:lord
@end group
@group
@end group
@end example

/*end-insert




@need 3200

@section Robustness Issues with Notifiers

Unfortunately, some fundamental physical properties of the universe
make it impossible for @code{notify} to guarantee that actions will be
invoked only once for each new category, branch, version, or revision.
A (presumably rare) well timed interrupt or system failure can cause
@code{notify} to invoke actions more than once for a given change to the
archive.  


Consequently, actions should be designed to be robust against that
eventuality.


@code{notify} is designed to be safe in the face of concurrent invocations:
if two processes invoke @code{notify} at the same time, everything should
work wonderfully with no resultant redundant actions or @code{NOTIFY-DIR}
corruptions.




@need 3200

@section Scheduling Notifiers with cron

One strategy for using @code{notify} is to run it from a @code{cron} job.




@need 3200

@section Scheduling Notifiers From arch Commands

@geindex my-notifier



These commands (and only these commands) modify arch repositories in
ways that are significant to @code{notify}:

@example
@group
        make-category
        make-branch
        make-version
        import
        commit
        tag
@end group
@group
@end group
@end example

If you register a notifier directory with the command @code{my-notifier}:

@example
@group
        % larch my-notifier NOTIFIER-DIR
@end group
@group
@end group
@end example

@noindent
then the commands listed above will, after completing their work,
spawn a detached daemon process that runs @code{larch notify} in that
directory.  Note that the start times and exit status of those daemons
are recorded in @code{~/.arch-params/log-file} which can be useful when
trying to debug problems.  You may want to clear that file from
time-to-time.







