Pass JOBSERIAL through to the cleanup function.
[whenjobs.git] / tools / whenjobs.pod
index 2acec9f..1c96648 100644 (file)
@@ -396,14 +396,18 @@ ran, then this evaluates to true, else false.
 
 This is the same as writing C<prev variable E<gt> variable>.
 
 
 This is the same as writing C<prev variable E<gt> variable>.
 
-B<Note:> There is a subtle and difficult problem with using the
-I<decreases> operator: The first time the expression is evaluated, the
-job has (by definition) not yet run.  Therefore C<prev variable>
-evaluates to C<""> (see definition of I<prev> above).  Since
-C<"" E<lt> everything>, the I<decreases> operator evaluates to
-false, and since this usually means the job does not run, the
-operator always evaluates to false.  A future version of whenjobs
-will address this problem.
+B<Note:> There is a subtle gotcha with the I<decreases> operator: The
+first time the expression is evaluated, the job has (by definition)
+not yet run.  Therefore C<prev variable> evaluates to C<""> (see
+definition of I<prev> above).  Since it is always true that
+
+ "" < anything
+
+the I<decreases> operator evaluates to false, and since this usually
+means the job does not run, the operator always evaluates to false.
+
+To fix this, ensure that the variable is initialized (see
+L</SETTING THE INITIAL VALUE OF VARIABLES> below).
 
 =item B<reloaded ()>
 
 
 =item B<reloaded ()>
 
@@ -411,9 +415,7 @@ This evaluates to true the first time the expression is evaluated
 after the jobs file has been reloaded or the daemon restarted.
 Thereafter it evaluates to false.
 
 after the jobs file has been reloaded or the daemon restarted.
 Thereafter it evaluates to false.
 
-You can use this to initialize variables, but note that this does not
-solve the I<decreases> operator problem described above, because
-variables are initialized too late to affect that.
+Don't use this to initialize variables: it won't do what you mean.
 
 =item B<false>
 
 
 =item B<false>
 
@@ -513,12 +515,163 @@ with C<job "name">:
 The job name is passed to the shell script in the C<$JOBNAME>
 environment variable.
 
 The job name is passed to the shell script in the C<$JOBNAME>
 environment variable.
 
+=head2 OCAML EXPRESSIONS
+
+As well as simple "every" and "when" expressions, advanced users may
+want to use arbitrary OCaml expressions, functions, etc in the jobs
+script.  These are useful for factoring common code or strings, for
+setting the initial values of variables, or for defining cleanup
+functions.
+
+A simple example of an OCaml expression is:
+
+ let prefix = "daily_"
+ job (prefix ^ "virus_scan")
+ every day :
+ <<
+   # ...
+ >>
+ job (prefix ^ "disk_check")
+ every day :
+ <<
+   # ...
+ >>
+
+which creates two jobs called C<"daily_virus_scan"> and
+C<"daily_disk_check"> (C<^> is the OCaml string concatenation
+operator).
+
+OCaml expressions have access to a library of functions called
+B<Whentools> which is described below.  It lets you set variables,
+create jobs algorithmically, etc.
+
+The OCaml expressions run once, when the jobs file is being loaded or
+reloaded.
+
+=head3 SETTING THE INITIAL VALUE OF VARIABLES
+
+Variables are created when they are referenced, and until set they
+have the value empty string (just like the shell).  Across file
+reloads, the previous values of variables is preserved.
+
+To initialize a variable to a known value when the jobs file is
+loaded, call one of the C<Whentools.set_variable*> functions as in
+this example:
+
+ let () =
+   Whentools.set_variable "name" "Richard";
+   Whentools.set_variable_int "counter" 0
+
+=head3 CLEANUP FUNCTIONS
+
+After a job runs, you can control what happens to its output by
+writing a cleanup function.  To write a cleanup function you have to
+name the job (ie. have an explicit C<job> statement).  Put C<cleanup ...>
+after the job name like this:
+
+ job "poll source"
+ cleanup (Whentools.mailto "you@example.com")
+ every 10 seconds :
+ <<
+   # ...
+ >>
+
+A number of cleanup functions are available in the library; see below.
+
+You can also write your own cleanup functions (in OCaml).  The
+function is passed one argument which is a C<Whentools.result> struct,
+defined below.
+
+=head3 WHENTOOLS LIBRARY
+
+=head4 Functions
+
+=over 4
 
 
+=item B<Whentools.mailto> [I<~only_on_failure:true>]
+[I<~from:from_address>] I<email_address> I<result>
 
 
+Send the result of the script by email to the given email address.
 
 
+If the optional C<~only_on_failure:true> flag is set, then it is only
+sent out if the script failed.
 
 
+If the optional C<~from> flag is set, then the from address is set
+accordingly.  This is sometimes needed when sending mail.
 
 
+Note the C<result> parameter is passed implicitly by the daemon.  You
+do not need to add it.
 
 
+Here are some examples of using the mailto function:
+
+ job "ex.1"
+ cleanup (Whentools.mailto "you@example.com")
+ every 10 seconds :
+ <<
+   # do something
+ >>
+
+ job "ex.2"
+ cleanup (Whentools.mailto ~only_on_failure:true
+                           "you@example.com")
+ every 10 seconds :
+ <<
+   # do something
+ >>
+
+ let from = "me@example.com"
+ let to_addr = "you@example.com"
+ job "ex.3"
+ cleanup (Whentools.mailto ~from to_addr)
+ every 10 seconds :
+ <<
+   # do something
+ >>
+
+=item B<Whentools.set_variable> I<name> I<string>
+
+Set variable I<name> to the string.
+
+=item B<Whentools.set_variable_bool> I<name> I<b>
+
+Set variable I<name> to the boolean value I<b>.
+
+=item B<Whentools.set_variable_int> I<name> I<i>
+
+Set variable I<name> to the integer value I<i>.
+
+=item B<Whentools.set_variable_string> I<name> I<s>
+
+Set variable I<name> to the string value <s>.  This is
+the same as I<Whentools.set_variable>.
+
+=item B<Whentools.set_variable_float> I<name> I<f>
+
+Set variable I<name> to the floating point value I<f>.
+
+=back
+
+=head4 Structures
+
+=over 4
+
+=item B<Whentools.result>
+
+This structure is passed to cleanup functions.  It has the following
+fields:
+
+ type result = {
+   res_job_name : string; # job name
+   res_serial : big_int;  # job serial (same as $JOBSERIAL)
+   res_code : int;        # return code from the shell script
+   res_tmpdir : string;   # temporary directory script ran in
+   res_output : string;   # filename of stdout/stderr output
+ }
+
+=back
 
 =head1 FILES
 
 
 =head1 FILES