Implement 'whenjobs --daemon-stop'
[whenjobs.git] / daemon / daemon.ml
index 3aee15a..347aff7 100644 (file)
@@ -45,6 +45,9 @@ let jobsdir = ref ""
 (* Was debugging requested on the command line? *)
 let debug = ref false
 
+(* The server. *)
+let server = ref None
+
 let esys = Unixqueue.standard_event_system ()
 let timer_group = ref None
 
@@ -58,12 +61,13 @@ let rec init j d =
   let addr = sprintf "%s/socket" !jobsdir in
   (try unlink addr with Unix_error _ -> ());
 
-  ignore (
+  server := Some (
     Whenproto_srv.When.V1.create_server
       ~proc_reload_file
       ~proc_set_variable
       ~proc_get_variable
       ~proc_get_variable_names
+      ~proc_exit_daemon
       (Rpc_server.Unix addr)
       Rpc.Tcp (* not TCP, this is the same as SOCK_STREAM *)
       Rpc.Socket
@@ -104,6 +108,17 @@ and proc_get_variable_names () =
   Array.sort compare vars;
   vars
 
+and proc_exit_daemon () =
+  if !debug then Syslog.notice "remote call: exit_daemon";
+
+  match !server with
+  | None ->
+    `error "exit_daemon: no server handle"
+  | Some s ->
+    Rpc_server.stop_server ~graceful:true s;
+    server := None;
+    `ok
+
 (* Reload the jobs file. *)
 and reload_file () =
   let file = sprintf "%s/jobs.cmo" !jobsdir in
@@ -166,7 +181,13 @@ and reevaluate_whenjobs jobnames =
             with Not_found -> assert false in
           assert (jobname = job.job_name);
 
-          let r, job' = job_evaluate job !variables in
+          let r, job' =
+            try job_evaluate job !variables
+            with Invalid_argument err | Failure err ->
+              Syslog.error "error evaluating job %s (at %s): %s"
+                jobname (Camlp4.PreCast.Ast.Loc.to_string job.job_loc) err;
+              false, job in
+
           jobs := StringMap.add jobname job' !jobs;
 
           if !debug then
@@ -244,7 +265,7 @@ and schedule_next_everyjob () =
       let w = Unixqueue.new_wait_id esys in
       let t_diff = t -. Unix.time () in
       let t_diff = if t_diff < 0. then 0. else t_diff in
-      Unixqueue.add_resource esys g (Unixqueue.Wait w, t_diff);
+      Unixqueue.add_weak_resource esys g (Unixqueue.Wait w, t_diff);
       let run_jobs _ _ _ =
         List.iter run_job jobs;
         delete_timer ();