Fossil SCM

Add the --poll option to "fossil backoffice" to allow it to act as a backoffice launch daemon.

drh 2019-03-07 17:57 trunk
Commit 1021afc6aa3ea77c9d242b948f306e02c47f5769e76f22cc2b4348ee5e5404b4
1 file changed +52 -19
+52 -19
--- src/backoffice.c
+++ src/backoffice.c
@@ -80,10 +80,11 @@
8080
# include <signal.h>
8181
# include <errno.h>
8282
# include <fcntl.h>
8383
# define GETPID getpid
8484
#endif
85
+#include <time.h>
8586
8687
/*
8788
** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice
8889
** processing run is valid. Each backoffice run monopolizes the lease for
8990
** at least this amount of time. Hopefully all backoffice processing is
@@ -546,51 +547,83 @@
546547
**
547548
** Run backoffice processing on the repositories listed. If no
548549
** repository is specified, run it on the repository of the local checkout.
549550
**
550551
** This might be done by a cron job or similar to make sure backoffice
551
-** processing happens periodically.
552
+** processing happens periodically. Or, the --poll option can be used
553
+** to run this command as a daemon that will periodically invoke backoffice
554
+** on collection of repositories.
555
+**
556
+** OPTIONS:
552557
**
553
-** Options:
558
+** --debug Show what this command is doing.
554559
**
555560
** --nodelay Do not queue up or wait for a backoffice job
556561
** to complete. If no work is available or if
557562
** backoffice has run recently, return immediately.
558563
** The --nodelay option is implied if more than
559564
** one repository is listed on the command-line.
560565
**
566
+** --poll N Repeat backoffice calls for repositories that
567
+** change in appoximately N-second intervals.
568
+** N less than 1 turns polling off (the default).
569
+**
561570
** --trace Enable debugging output on stderr
562571
*/
563572
void backoffice_command(void){
573
+ int nPoll;
574
+ const char *zPoll;
575
+ int bDebug = 0;
576
+ unsigned int nCmd = 0;
564577
if( find_option("trace",0,0)!=0 ) g.fAnyTrace = 1;
565578
if( find_option("nodelay",0,0)!=0 ) backofficeNoDelay = 1;
579
+ zPoll = find_option("poll",0,1);
580
+ nPoll = zPoll ? atoi(zPoll) : 0;
581
+ bDebug = find_option("debug",0,0)!=0;
566582
567583
/* Silently consume the -R or --repository flag, leaving behind its
568584
** argument. This is for legacy compatibility. Older versions of the
569585
** backoffice command only ran on a single repository that was specified
570586
** using the -R option. */
571587
(void)find_option("repository","R",0);
572588
573589
verify_all_options();
574
- if( g.argc>3 ){
575
- /* Multiple repositories named on the command-line. Run each in a
576
- ** separate sub-process */
590
+ if( g.argc>3 || nPoll>0 ){
591
+ /* Either there are multiple repositories named on the command-line
592
+ ** or we are polling. In either case, each backoffice should be run
593
+ ** using a separate sub-process */
577594
int i;
578
- for(i=2; i<g.argc; i++){
579
- Blob cmd;
580
- blob_init(&cmd, 0, 0);
581
- blob_append_escaped_arg(&cmd, g.nameOfExe);
582
- blob_append(&cmd, " backoffice --nodelay", -1);
583
- if( g.fAnyTrace ){
584
- blob_append(&cmd, " --trace", -1);
585
- }
586
- blob_append_escaped_arg(&cmd, g.argv[i]);
587
- if( g.fAnyTrace ){
588
- fossil_print("-- %s\n", blob_str(&cmd));
589
- }
590
- fossil_system(blob_str(&cmd));
591
- blob_reset(&cmd);
595
+ time_t iNow = 0;
596
+ time_t ix;
597
+ while( 1 /* exit via "break;" */){
598
+ time_t iNext = time(0);
599
+ for(i=2; i<g.argc; i++){
600
+ Blob cmd;
601
+ if( !file_isfile(g.argv[i], ExtFILE) ) continue;
602
+ if( iNow && iNow>file_mtime(g.argv[i],ExtFILE) ) continue;
603
+ blob_init(&cmd, 0, 0);
604
+ blob_append_escaped_arg(&cmd, g.nameOfExe);
605
+ blob_append(&cmd, " backoffice --nodelay", -1);
606
+ if( g.fAnyTrace ){
607
+ blob_append(&cmd, " --trace", -1);
608
+ }
609
+ blob_append_escaped_arg(&cmd, g.argv[i]);
610
+ nCmd++;
611
+ if( bDebug ){
612
+ fossil_print("COMMAND[%u]: %s\n", nCmd, blob_str(&cmd));
613
+ }
614
+ fossil_system(blob_str(&cmd));
615
+ blob_reset(&cmd);
616
+ }
617
+ if( nPoll<1 ) break;
618
+ iNow = iNext;
619
+ ix = time(0);
620
+ if( ix < iNow+nPoll ){
621
+ sqlite3_int64 nMS = (iNow + nPoll - ix)*1000;
622
+ if( bDebug )fossil_print("SLEEP: %lld\n", nMS);
623
+ sqlite3_sleep((int)nMS);
624
+ }
592625
}
593626
}else{
594627
if( g.argc==3 ){
595628
g.zRepositoryOption = g.argv[2];
596629
g.argc--;
597630
--- src/backoffice.c
+++ src/backoffice.c
@@ -80,10 +80,11 @@
80 # include <signal.h>
81 # include <errno.h>
82 # include <fcntl.h>
83 # define GETPID getpid
84 #endif
 
85
86 /*
87 ** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice
88 ** processing run is valid. Each backoffice run monopolizes the lease for
89 ** at least this amount of time. Hopefully all backoffice processing is
@@ -546,51 +547,83 @@
546 **
547 ** Run backoffice processing on the repositories listed. If no
548 ** repository is specified, run it on the repository of the local checkout.
549 **
550 ** This might be done by a cron job or similar to make sure backoffice
551 ** processing happens periodically.
 
 
 
 
552 **
553 ** Options:
554 **
555 ** --nodelay Do not queue up or wait for a backoffice job
556 ** to complete. If no work is available or if
557 ** backoffice has run recently, return immediately.
558 ** The --nodelay option is implied if more than
559 ** one repository is listed on the command-line.
560 **
 
 
 
 
561 ** --trace Enable debugging output on stderr
562 */
563 void backoffice_command(void){
 
 
 
 
564 if( find_option("trace",0,0)!=0 ) g.fAnyTrace = 1;
565 if( find_option("nodelay",0,0)!=0 ) backofficeNoDelay = 1;
 
 
 
566
567 /* Silently consume the -R or --repository flag, leaving behind its
568 ** argument. This is for legacy compatibility. Older versions of the
569 ** backoffice command only ran on a single repository that was specified
570 ** using the -R option. */
571 (void)find_option("repository","R",0);
572
573 verify_all_options();
574 if( g.argc>3 ){
575 /* Multiple repositories named on the command-line. Run each in a
576 ** separate sub-process */
 
577 int i;
578 for(i=2; i<g.argc; i++){
579 Blob cmd;
580 blob_init(&cmd, 0, 0);
581 blob_append_escaped_arg(&cmd, g.nameOfExe);
582 blob_append(&cmd, " backoffice --nodelay", -1);
583 if( g.fAnyTrace ){
584 blob_append(&cmd, " --trace", -1);
585 }
586 blob_append_escaped_arg(&cmd, g.argv[i]);
587 if( g.fAnyTrace ){
588 fossil_print("-- %s\n", blob_str(&cmd));
589 }
590 fossil_system(blob_str(&cmd));
591 blob_reset(&cmd);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
592 }
593 }else{
594 if( g.argc==3 ){
595 g.zRepositoryOption = g.argv[2];
596 g.argc--;
597
--- src/backoffice.c
+++ src/backoffice.c
@@ -80,10 +80,11 @@
80 # include <signal.h>
81 # include <errno.h>
82 # include <fcntl.h>
83 # define GETPID getpid
84 #endif
85 #include <time.h>
86
87 /*
88 ** The BKOFCE_LEASE_TIME is the amount of time for which a single backoffice
89 ** processing run is valid. Each backoffice run monopolizes the lease for
90 ** at least this amount of time. Hopefully all backoffice processing is
@@ -546,51 +547,83 @@
547 **
548 ** Run backoffice processing on the repositories listed. If no
549 ** repository is specified, run it on the repository of the local checkout.
550 **
551 ** This might be done by a cron job or similar to make sure backoffice
552 ** processing happens periodically. Or, the --poll option can be used
553 ** to run this command as a daemon that will periodically invoke backoffice
554 ** on collection of repositories.
555 **
556 ** OPTIONS:
557 **
558 ** --debug Show what this command is doing.
559 **
560 ** --nodelay Do not queue up or wait for a backoffice job
561 ** to complete. If no work is available or if
562 ** backoffice has run recently, return immediately.
563 ** The --nodelay option is implied if more than
564 ** one repository is listed on the command-line.
565 **
566 ** --poll N Repeat backoffice calls for repositories that
567 ** change in appoximately N-second intervals.
568 ** N less than 1 turns polling off (the default).
569 **
570 ** --trace Enable debugging output on stderr
571 */
572 void backoffice_command(void){
573 int nPoll;
574 const char *zPoll;
575 int bDebug = 0;
576 unsigned int nCmd = 0;
577 if( find_option("trace",0,0)!=0 ) g.fAnyTrace = 1;
578 if( find_option("nodelay",0,0)!=0 ) backofficeNoDelay = 1;
579 zPoll = find_option("poll",0,1);
580 nPoll = zPoll ? atoi(zPoll) : 0;
581 bDebug = find_option("debug",0,0)!=0;
582
583 /* Silently consume the -R or --repository flag, leaving behind its
584 ** argument. This is for legacy compatibility. Older versions of the
585 ** backoffice command only ran on a single repository that was specified
586 ** using the -R option. */
587 (void)find_option("repository","R",0);
588
589 verify_all_options();
590 if( g.argc>3 || nPoll>0 ){
591 /* Either there are multiple repositories named on the command-line
592 ** or we are polling. In either case, each backoffice should be run
593 ** using a separate sub-process */
594 int i;
595 time_t iNow = 0;
596 time_t ix;
597 while( 1 /* exit via "break;" */){
598 time_t iNext = time(0);
599 for(i=2; i<g.argc; i++){
600 Blob cmd;
601 if( !file_isfile(g.argv[i], ExtFILE) ) continue;
602 if( iNow && iNow>file_mtime(g.argv[i],ExtFILE) ) continue;
603 blob_init(&cmd, 0, 0);
604 blob_append_escaped_arg(&cmd, g.nameOfExe);
605 blob_append(&cmd, " backoffice --nodelay", -1);
606 if( g.fAnyTrace ){
607 blob_append(&cmd, " --trace", -1);
608 }
609 blob_append_escaped_arg(&cmd, g.argv[i]);
610 nCmd++;
611 if( bDebug ){
612 fossil_print("COMMAND[%u]: %s\n", nCmd, blob_str(&cmd));
613 }
614 fossil_system(blob_str(&cmd));
615 blob_reset(&cmd);
616 }
617 if( nPoll<1 ) break;
618 iNow = iNext;
619 ix = time(0);
620 if( ix < iNow+nPoll ){
621 sqlite3_int64 nMS = (iNow + nPoll - ix)*1000;
622 if( bDebug )fossil_print("SLEEP: %lld\n", nMS);
623 sqlite3_sleep((int)nMS);
624 }
625 }
626 }else{
627 if( g.argc==3 ){
628 g.zRepositoryOption = g.argv[2];
629 g.argc--;
630

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button