static sqlite3 *db; // single connection, serialized across all our threads!
static unsigned verbose;
static volatile sig_atomic_t interrupted = 0;
+static volatile sig_atomic_t forced_rescan_count = 0;
static volatile sig_atomic_t sigusr1 = 0;
+static volatile sig_atomic_t forced_groom_count = 0;
static volatile sig_atomic_t sigusr2 = 0;
static unsigned http_port = 8002;
static unsigned rescan_s = 300;
cv.notify_all();
}
+ // clear the workqueue, when scanning is interrupted with USR2
+ void clear() {
+ unique_lock<mutex> lock(mtx);
+ q.clear();
+ set_metric("thread_work_pending","role","scan", q.size());
+ cv.notify_all(); // maybe wake up waiting idlers
+ }
+
// block this scanner thread until there is work to do and no active
bool wait_front (Payload& p)
{
}
inc_metric("thread_work_total", "role","scan");
+
+ if (sigusr2 != forced_groom_count) // stop early if groom triggered
+ {
+ scanq.clear();
+ break;
+ }
}
add_metric("thread_busy", "role", "scan", -1);
{
if (interrupted) break;
+ if (sigusr2 != forced_groom_count) // stop early if groom triggered
+ break;
+
fts_scanned ++;
if (verbose > 2)
{
(void) arg; // ignore; we operate on global data
- sig_atomic_t forced_rescan_count = 0;
set_metric("thread_tid", "role","traverse", tid());
add_metric("thread_count", "role", "traverse", 1);
struct timeval tv_start, tv_end;
gettimeofday (&tv_start, NULL);
+ database_stats_report();
+
// scan for files that have disappeared
sqlite_ps files (db, "check old files", "select s.mtime, s.file, f.name from "
BUILDIDS "_file_mtime_scanned s, " BUILDIDS "_files f "
files_del_r_de.reset().bind(1,fileid).bind(2,mtime).step_ok_done();
files_del_scan.reset().bind(1,fileid).bind(2,mtime).step_ok_done();
}
+
+ inc_metric("thread_work_total", "role", "groom");
+ if (sigusr1 != forced_rescan_count) // stop early if scan triggered
+ break;
}
files.reset();
static void*
thread_main_groom (void* /*arg*/)
{
- sig_atomic_t forced_groom_count = 0;
set_metric("thread_tid", "role", "groom", tid());
add_metric("thread_count", "role", "groom", 1);
set_metric("thread_busy", "role", "groom", 1);
groom ();
last_groom = time(NULL); // NB: now was before grooming
- inc_metric("thread_work_total", "role", "groom");
set_metric("thread_busy", "role", "groom", 0);
}
catch (const sqlite_exception& e)
the index also stores the file mtimes). A time of zero is acceptable,
and means that only one initial scan should performed. The default
rescan time is 300 seconds. Receiving a SIGUSR1 signal triggers a new
-scan, independent of the rescan time (including if it was zero).
+scan, independent of the rescan time (including if it was zero),
+interrupting a groom pass (if any).
.TP
.B "\-g SECONDS" "\-\-groom\-time=SECONDS"
section. The default groom time is 86400 seconds (1 day). A time of
zero is acceptable, and means that only one initial groom should be
performed. Receiving a SIGUSR2 signal triggers a new grooming pass,
-independent of the groom time (including if it was zero).
+independent of the groom time (including if it was zero), interrupting
+a rescan pass (if any)..
.TP
.B "\-G"
rm -r R/debuginfod-rpms/rhel6/*
kill -USR2 $PID1 # groom cycle
# Expect 3 rpms to be deleted by the groom
-# 1 groom already took place at/soon-after startup, so -USR2 makes 2
-wait_ready $PORT1 'thread_work_total{role="groom"}' 2
+# 1 groom cycle already took place at/soon-after startup, so -USR2 makes 2
+# ... times the # of files checked in each cycle
+wait_ready $PORT1 'thread_work_total{role="groom"}' 51
wait_ready $PORT1 'groom{statistic="file d/e"}' 3
rm -rf $DEBUGINFOD_CACHE_PATH # clean it from previous tests
# run a groom cycle to force server to drop its fdcache
kill -USR2 $PID1 # groom cycle
-wait_ready $PORT1 'thread_work_total{role="groom"}' 3
+wait_ready $PORT1 'thread_work_total{role="groom"}' 98 # 3 complete cycles
# move it around a couple of times to make it likely to hit a nonexistent entry during iteration
mv R/debuginfod-rpms/rhel7 R/debuginfod-rpms/rhel7renamed
kill -USR1 $PID1 # scan cycle