The Hackerlab at `regexps.com`

## arch Triggers

up: arch next: Using Triggers prev: Revision Tree Libraries

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 `notify` provides this capability:

            % larch notify NOTIFICATION-DIR

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

This chapter explains `notify` in general. It documents the format of a `NOTIFICATION-DIR` and the configuration files. It explains what `notify` does. Later in the manual is documentation explaining how to use `notify` to achieve certain specific effects.

### The Four notify Configuration Files

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

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

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

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

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

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

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

The file `=rules.versions` contains lines with the format:

            VERSION         ACTION

where `VERSION` is a fully-qualified version name, and action a string (with no whitespace) of the form:

            COMMAND:THUNK

Whenever new revisions are detected in `VERSION` , `notify` invokes:

            larch COMMAND THUNK RVN ...

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

The file `=rules.branches` is similar. It contains lines of the form:

            BRANCH COMMAND:THUNK VERSION-ACTION

Whenever new versions are created in `BRANCH` , `notify` takes two actions. First, it invokes:

            larch COMMAND THUNK VSN ...

Second, it adds new rules to `=rules.versions` of the form:

            VSN     VERSION-ACTION

The files `=rules.categories` and `=rules.archives` are similar. The former contains lines of the form:

            CATEGORY COMMAND:THUNK BRANCH-ACTION VERSION-ACTION

and the latter lines of the form:

            ARCHIVE COMMAND:THUNK CATEGORY-ACT BRANCH-ACT VERSION-ACT

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

### Triggers for Everything in a Repository

Configuring triggers for every category, branch, and version in an archive is quite simple: you only need to write the `=rules.archives` file -- other configuration files will be automatically genrated from that.

The initial `=rules.archives` file should contain lines of the form:

            ARCHIVE COMMAND:THUNK CATEGORY-ACT BRANCH-ACT VERSION-ACT

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

            CATEGORY CATEGORY-ACT BRANCH-ACT VERSION-ACT

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

Finally, `=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 `notify` is run, of course).

### Robustness Issues with Triggers

Unfortunately, some fundamental physical properties of the universe make it impossible for `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 `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.

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

### Scheduling Triggers with cron

One strategy for using `notify` is to run it from a `cron` job.

### Scheduling Triggers Directly

These commands (and only these commands) modify arch repositories in ways that are significant to `notify` :

            make-category
            make-branch
            make-version
            import
            commit

Corresponding to those commands, are four others:

            % larch my-category-action COMMAND ARGUMENTS...

            % larch my-branch-action COMMAND ARGUMENTS...

            % larch my-version-action COMMAND ARGUMENTS...

            % larch my-revision-action COMMAND ARGUMENTS...

which in those invocations, set an action to be taken upon successful completion of an archive transaction, and in these invocations:

            % larch my-category-action

            % larch my-branch-action

            % larch my-version-action

            % larch my-revision-action

report the actions to be taken.

The actions have a fairly obvious meaning. After creating a new branch, for example, the command `make-branch` will invoke:

            % COMMAND ARGUMENTS... BRANCH

where `BRANCH` is a fully qualified branch name.

A useful action to take is to invoke `notify` directly. Another useful action (though imposing a greater system administration burden) is to invoke a script which sends mail to some address, informing the recipient of the repository change. The recipient can be, for example, an automated process which invokes `notify` .

When the repository-modifying commands invoke one of these actions, they run the action as a `daemon` : an asynchronous process with no controlling terminal, with standard input redirected from `/dev/null` , and with `stdout` and `stderr` saved in a temporary file. If the command exits with non-0 status, the output from the command is sent to the user in an email notice.

Once again, the damn constraints of physics, particularly the prohibition against "action at a distance", impose a constraint: it is impossible to guarantee the `COMMAND` will be invoked and in (hopefully rare) circumstances, it might not be. `COMMANDs` should be chosen with that constraint in mind.

arch: The arch Revision Control System
The Hackerlab at `regexps.com`