[whenjobs] Add upstream patch for persisting variables across runs.

Richard W.M. Jones rjones at fedoraproject.org
Sat Aug 18 15:24:04 UTC 2012


commit 67e692526b2795d6e3d75f1b93642d4304bb45b3
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Sat Aug 18 16:04:21 2012 +0100

    Add upstream patch for persisting variables across runs.

 ...ist-variables-to-file-.whenjobs-variables.patch |  294 ++++++++++++++++++++
 whenjobs.spec                                      |   10 +-
 2 files changed, 303 insertions(+), 1 deletions(-)
---
diff --git a/0001-Persist-variables-to-file-.whenjobs-variables.patch b/0001-Persist-variables-to-file-.whenjobs-variables.patch
new file mode 100644
index 0000000..da298b7
--- /dev/null
+++ b/0001-Persist-variables-to-file-.whenjobs-variables.patch
@@ -0,0 +1,294 @@
+From 080d38e64fe2aaec17e3ff853682188196b429f9 Mon Sep 17 00:00:00 2001
+From: "Richard W.M. Jones" <rjones at redhat.com>
+Date: Sat, 18 Aug 2012 15:40:23 +0100
+Subject: [PATCH] Persist variables to file (~/.whenjobs/variables).
+
+---
+ Makefile.am                                  |    3 +-
+ configure.ac                                 |    1 +
+ daemon/daemon.ml                             |   84 +++++++++++++++++++++++++-
+ tests/variables/Makefile.am                  |   21 +++++++
+ tests/variables/test-persistent-variables.sh |   71 ++++++++++++++++++++++
+ 5 files changed, 176 insertions(+), 4 deletions(-)
+ create mode 100644 tests/variables/Makefile.am
+ create mode 100755 tests/variables/test-persistent-variables.sh
+
+diff --git a/Makefile.am b/Makefile.am
+index 069636d..fe9594b 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -24,7 +24,8 @@ SUBDIRS = \
+ 	daemon \
+ 	tools \
+ 	tests/parsing \
+-	tests/jobs
++	tests/jobs \
++	tests/variables
+ 
+ CLEANFILES = *~
+ 
+diff --git a/configure.ac b/configure.ac
+index ea13ef8..a838c49 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -118,6 +118,7 @@ AC_CONFIG_FILES([Makefile
+                  lib/Makefile
+                  tests/jobs/Makefile
+                  tests/parsing/Makefile
++                 tests/variables/Makefile
+                  tools/Makefile
+                  whenjobs.spec])
+ AC_OUTPUT
+diff --git a/daemon/daemon.ml b/daemon/daemon.ml
+index 078aa3a..f5ba4ff 100644
+--- a/daemon/daemon.ml
++++ b/daemon/daemon.ml
+@@ -29,9 +29,41 @@ external _exit : int -> 'a = "whenjobs__exit"
+ (* $HOME/.whenjobs *)
+ let jobsdir = ref ""
+ 
+-(* The state. *)
++(* The state.
++ *
++ * Note that whenever this is updated, you need to consider if you
++ * should call 'save_variables ()' (which persists the variables to a
++ * file).  XXX We should replace this ref with an accessor
++ * function.
++ *)
+ let state = ref Whenstate.empty
+ 
++(* Format used to save variables.  Note we can't allow any internal
++ * types to "escape" into this definition, else the file format will
++ * change when parts of the program change.
++ *)
++type variables_file_v1 = (string * variable_v1) list
++and variable_v1 =
++  | Vv1_unit
++  | Vv1_bool of bool
++  | Vv1_string of string
++  | Vv1_int of big_int
++  | Vv1_float of float
++
++let variable_of_variable_v1 = function
++  | Vv1_unit -> T_unit
++  | Vv1_bool b -> T_bool b
++  | Vv1_string s -> T_string s
++  | Vv1_int i -> T_int i
++  | Vv1_float f -> T_float f
++
++let variable_v1_of_variable = function
++  | T_unit -> Vv1_unit
++  | T_bool b -> Vv1_bool b
++  | T_string s -> Vv1_string s
++  | T_int i -> Vv1_int i
++  | T_float f -> Vv1_float f
++
+ (* Jobs that are running: a map of PID -> (job, tmpdir, serial, start_time).
+  * Note that the job may no longer exist *OR* it may have been renamed,
+  * eg. if the jobs file was reloaded.
+@@ -93,8 +125,48 @@ let rec init j d =
+   (* Handle SIGCHLD to clean up jobs. *)
+   Sys.set_signal Sys.sigchld (Sys.Signal_handle handle_sigchld);
+ 
+-  (* Initialize the variables. *)
+-  state := Whenstate.set_variable !state "JOBSERIAL" (T_int zero_big_int)
++  (* Load or initialize the variables. *)
++  let variables_file = sprintf "%s/variables" !jobsdir in
++  state :=
++    try
++      let chan = open_in variables_file in
++      let r = load_variables !state chan in
++      close_in chan;
++      r
++    with
++    | Sys_error _ ->
++      Whenstate.set_variable !state "JOBSERIAL" (T_int zero_big_int)
++
++(* Try to load the variables from the file.  If the file exists and
++ * cannot be read, raise an exception.
++ *)
++and load_variables state chan =
++  let signature = input_line chan in
++  if signature = "WHENJOBS VARIABLES VERSION 1" then (
++    let variables : variables_file_v1 = input_value chan in
++    List.fold_left (
++      fun state (n, v) ->
++        Whenstate.set_variable state n (variable_of_variable_v1 v)
++    ) state variables
++  ) else (* in future, other signatures, but for now ... *)
++    failwith (sprintf "cannot read variables file: invalid signature: %s"
++                signature)
++
++and save_variables () =
++  let variables_file = sprintf "%s/variables" !jobsdir in
++  let new_file = variables_file ^ ".new" in
++  let chan = open_out new_file in
++  fprintf chan "WHENJOBS VARIABLES VERSION 1\n";
++  let variables = Whenstate.get_variables !state in
++  let variables =
++    List.map (fun (n, v) -> n, variable_v1_of_variable v) variables in
++  output_value chan variables;
++
++  (* Try to arrange that the new file is updated atomically. *)
++  flush chan;
++  Netsys_posix.fsync (descr_of_out_channel chan);
++  close_out chan;
++  rename new_file variables_file
+ 
+ and proc_reload_file () =
+   if !debug then Syslog.notice "remote call: reload_file";
+@@ -116,6 +188,7 @@ and proc_set_variable (name, value) =
+     let jobnames, state' = reevaluate_whenjobs !state jobs in
+     let state' = run_whenjobs state' jobnames in
+     state := state';
++    save_variables ();
+ 
+     `ok
+   with
+@@ -172,6 +245,7 @@ and proc_start_job jobname =
+     let job = Whenstate.get_job !state jobname in
+     let state' = run_job !state job in
+     state := state';
++    save_variables ();
+     `ok
+   with
+   | Not_found -> `error "job not found"
+@@ -218,6 +292,7 @@ and proc_set_variables vars =
+     let jobnames, state' = reevaluate_whenjobs !state jobs in
+     let state' = run_whenjobs state' jobnames in
+     state := state';
++    save_variables ();
+ 
+     `ok
+   with
+@@ -284,6 +359,7 @@ and proc_whisper_variables vars =
+       fun s (name, value) -> Whenstate.set_variable s name value
+     ) !state vars in
+     state := s;
++    save_variables ();
+ 
+     (* .. but don't reevaluate or run jobs. *)
+ 
+@@ -363,6 +439,7 @@ and reload_files () =
+   let jobnames, state' = reevaluate_whenjobs ~onload:true !state jobs in
+   let state' = run_whenjobs state' jobnames in
+   state := state';
++  save_variables ();
+ 
+   (* Schedule the next every job to run. *)
+   schedule_next_everyjob ()
+@@ -471,6 +548,7 @@ and schedule_next_everyjob () =
+         delete_timer_group ();          (* Delete the timer. *)
+         let state' = List.fold_left run_job !state jobs in
+         state := state';
++        save_variables ();
+         schedule_next_everyjob ()
+       in
+       Unixqueue.weak_once esys g t_diff run_jobs;
+diff --git a/tests/variables/Makefile.am b/tests/variables/Makefile.am
+new file mode 100644
+index 0000000..31af26e
+--- /dev/null
++++ b/tests/variables/Makefile.am
+@@ -0,0 +1,21 @@
++# whenjobs
++# Copyright (C) 2012 Red Hat Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++
++EXTRA_DIST = $(TESTS)
++
++TESTS = test-persistent-variables.sh
++
+diff --git a/tests/variables/test-persistent-variables.sh b/tests/variables/test-persistent-variables.sh
+new file mode 100755
+index 0000000..e069123
+--- /dev/null
++++ b/tests/variables/test-persistent-variables.sh
+@@ -0,0 +1,71 @@
++# whenjobs
++# Copyright (C) 2012 Red Hat Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++
++# Test that variables are reloaded across runs.
++
++unset CDPATH
++set -e
++
++testdir=$(pwd)
++libdir=$(cd ../../lib; pwd)
++toolsdir=$(cd ../../tools; pwd)
++daemondir=$(cd ../../daemon; pwd)
++
++HOME="$testdir"
++export HOME
++
++rm -rf "$testdir/.whenjobs"
++
++PATH="$toolsdir:$daemondir:$PATH"
++export PATH
++
++# Kill the daemon and clean up when the script exits.
++function cleanup {
++    kill `cat "$testdir/.whenjobs/daemon_pid"`
++    rm -rf "$testdir/.whenjobs"
++}
++trap cleanup INT TERM QUIT EXIT
++
++# Run the daemon.
++whenjobsd -d
++
++whenjobs --lib "$libdir" --type float --set test_float=4.2
++whenjobs --lib "$libdir" --type int --set test_int=42
++whenjobs --lib "$libdir" --type string --set test_string=fortytwo
++
++whenjobs --lib "$libdir" --daemon-stop >/dev/null 2>&1 ||:
++
++# Run the daemon again and read back the variables.
++whenjobsd -d
++
++output="$(whenjobs --lib "$libdir" --variables | LANG=C sort)"
++
++whenjobs --lib "$libdir" --daemon-stop >/dev/null 2>&1 ||:
++
++trap - INT TERM QUIT EXIT
++rm -rf "$testdir/.whenjobs"
++
++if [ "$output" != "JOBSERIAL=0
++test_float=4.2
++test_int=42
++test_string=fortytwo" ]; then
++    echo "$0: unexpected variables in output:"
++    echo "$output"
++    exit 1
++fi
++
++rm -rf "$testdir/.whenjobs"
+-- 
+1.7.10.4
+
diff --git a/whenjobs.spec b/whenjobs.spec
index 1c0ea43..be54daf 100644
--- a/whenjobs.spec
+++ b/whenjobs.spec
@@ -3,7 +3,7 @@
 
 Name:            whenjobs
 Version:         0.7.3
-Release:         1%{?dist}
+Release:         2%{?dist}
 Summary:         Replacement for cron with dependencies
 
 Group:           Development/Libraries
@@ -11,6 +11,8 @@ License:         GPLv2+
 URL:             http://people.redhat.com/~rjones/whenjobs
 Source0:         http://people.redhat.com/~rjones/whenjobs/files/%{name}-%{version}.tar.gz
 
+Patch0001:       0001-Persist-variables-to-file-.whenjobs-variables.patch
+
 BuildRequires:   ocaml >= 3.12.0
 BuildRequires:   ocaml-ocamldoc
 BuildRequires:   ocaml-findlib-devel
@@ -47,6 +49,9 @@ when another job has finished successfully).
 %prep
 %setup -q
 
+%patch0001 -p1
+chmod +x tests/variables/test-persistent-variables.sh
+
 rm lib/whenproto_aux.ml
 rm lib/whenproto_aux.mli
 
@@ -90,5 +95,8 @@ strip --strip-all $RPM_BUILD_ROOT%{_sbindir}/whenjobsd
 
 
 %changelog
+* Sat Aug 18 2012 Richard W.M. Jones <rjones at redhat.com> - 0.7.3-2
+- Add upstream patch for persisting variables across runs.
+
 * Fri Jul 20 2012 Richard W.M. Jones <rjones at redhat.com> - 0.7.3-1
 - Initial release (RHBZ#803089).


More information about the scm-commits mailing list