Hi,

On Wednesday 20 February 2008, Bastian Friedrich wrote:
> when configuring multiple "Run"s in a schedule that occur at the same time,
> they are run sequentially:
>   Run = Full Pool = PoolSpecial w01 mon at 8:00
>   Run = Full Pool = Pool mon at 8:00
> results in two executions of the job that refers to the schedule.
>
[...]
> I'd have a need for exclusiveness in this case: run the job only in case it
> is not referenced before. Would you also regard this as a sensible
> modification?

despite the fact that we found workarounds during our discussion (on 
bacula-users), I wrote a small patch:

With the attached patch, Schedule statements can include an 
optional "QueueOnce" flag (i.e. QueueOnce=true, with QueueOnce=false being 
default). If this flag is set, a job will only be queued once per minute. 
With this enabled, one can e.g. schedule a job "first of month" as well 
as "mondays"; the job will only be queued once if a monday is a first of a 
month as well, and both events were queued for the same minute.

This modifies the current behavior, where jobs were queued twice.

Because of Bacula's internal logic, the _last_ "Run" statement in a schedule 
wins; we can understand this as "overwriting" statements.

What do you think about this idea/code?

Oh, btw: the attached patch is against SVN trunk.

Thx, Best regards,
   Bastian

-- 
Collax GmbH . Burkheimer Straße 3 . 79111 Freiburg . Germany
p: +49 (0) 761-45684-24
f: +49 (0) 761-45684-10        www.collax.com

Geschäftsführer: William K. Hite / Boris Nalbach
AG München HRB 158898 . Ust.-IdNr: DE 814464942
\ Machine-independent: does not run on any existing machine.
Index: src/dird/scheduler.c
===================================================================
--- src/dird/scheduler.c	(revision 6461)
+++ src/dird/scheduler.c	(working copy)
@@ -67,7 +67,7 @@
 
 /* Forward referenced subroutines */
 static void find_runs();
-static void add_job(JOB *job, RUN *run, time_t now, time_t runtime);
+static void add_job(JOB *job, RUN *run, SCHED *sched, time_t now, time_t runtime);
 static void dump_job(job_item *ji, const char *msg);
 
 /* Imported subroutines */
@@ -364,11 +364,11 @@
 	   tm.tm_sec = 0;               /* zero secs */
 	   runtime = mktime(&tm);
 	   if (run_now) {
-	     add_job(job, run, now, runtime);
+	     add_job(job, run, sched, now, runtime);
 	   }
 	   /* If job is to be run in the next hour schedule it */
 	   if (run_nh) {
-	     add_job(job, run, now, runtime + 3600);
+	     add_job(job, run, sched, now, runtime + 3600);
 	   }
 	 }
       }
@@ -377,7 +377,7 @@
    Dmsg0(dbglvl, "Leave find_runs()\n");
 }
 
-static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
+static void add_job(JOB *job, RUN *run, SCHED *sched, time_t now, time_t runtime)
 {
    job_item *ji;
    bool inserted = false;
@@ -397,6 +397,32 @@
 #endif
       return;
    }
+
+    /*
+     * If schedule permits only one execution per minute ("QueueOnce" set),
+     * search for existing queue entries within one minute. Drop if found.
+     */
+    if (sched->queueonce) {
+       foreach_dlist(ji, jobs_to_run) {
+          if (!strcmp(ji->job->hdr.name, job->hdr.name) &&
+            (abs(ji->runtime - runtime) < 60)) {
+
+             char dt[50], dt1[50], dt2[50];
+             bstrftime_nc(dt, sizeof(dt), ji->runtime);
+             bstrftime_nc(dt1, sizeof(dt1), runtime);
+             Dmsg5(dbglvl, "Duplicate queue entry for job %s, QueueOnce enabled. "
+			     "Queued runtime=%s(%x), dropped runtime = %s(%x).\n",
+			     job->hdr.name,
+			     dt,
+			     ji->runtime,
+			     dt1,
+			     runtime);
+             fflush(stdout);
+             return;
+          }
+       }
+    }
+
 #ifdef SCHED_DEBUG
    Dmsg4(000, "Add: Job=\"%s\" run=%x last_run=%x now=%x\n", job->hdr.name, 
             runtime, run->last_run, now);
Index: src/dird/dird_conf.c
===================================================================
--- src/dird/dird_conf.c	(revision 6454)
+++ src/dird/dird_conf.c	(working copy)
@@ -347,6 +347,7 @@
    {"name",     store_name,  ITEM(res_sch.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str, ITEM(res_sch.hdr.desc), 0, 0, 0},
    {"run",      store_run,   ITEM(res_sch.run),      0, 0, 0},
+   {"queueonce", store_bool, ITEM(res_sch.queueonce), 0, ITEM_DEFAULT, false},
    {NULL, NULL, {0}, 0, 0, 0}
 };
 
Index: src/dird/dird_conf.h
===================================================================
--- src/dird/dird_conf.h	(revision 6454)
+++ src/dird/dird_conf.h	(working copy)
@@ -492,6 +492,8 @@
    RES   hdr;
 
    RUN *run;
+
+   bool queueonce;
 };
 
 /*
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Bacula-users mailing list
Bacula-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-users

Reply via email to