BareGit

Stagger initial probe scheduling

Assign each service a uniform initial due time across its configured
interval so startup probes do not arrive in one burst. Update scheduler
documentation and tests for the randomized startup phase.
Author: MetroWind <chris.corsair@gmail.com>
Date: Sun Sep 20 21:15:27 2026 -0700
Commit: 6e9768fa25f26183f538a98d2a2827d4c07143fc

Changes

diff --git a/prd.md b/prd.md
index 856a17c..53c9d0b 100644
--- a/prd.md
+++ b/prd.md
@@ -80,7 +80,8 @@ A simple self-hosted service status tracker.
 - Probe workflow:
   1. A priority queue of tasks, ordered by next due time.
   2. Each endpoint has an atomic bool `in_flight`.
-  3. The scheduler dequeues a task. If the endpoint is already in flight,
+  3. The scheduler gives each endpoint a random initial due time between now
+     and the end of its interval. If the endpoint is already in flight,
      skip this occurrence; otherwise mark it in flight and wait for a
      worker. Shutdown or an execution error cancels this wait.
   4. The scheduler enqueue the next task of that endpoint. Note that
diff --git a/src/scheduler.cpp b/src/scheduler.cpp
index d73e68a..0f0e67b 100644
--- a/src/scheduler.cpp
+++ b/src/scheduler.cpp
@@ -1,5 +1,6 @@
 #include "scheduler.h"
 
+#include <random>
 #include <string_view>
 #include <utility>
 
@@ -141,9 +142,14 @@ mw::E<void> Scheduler::run(std::stop_token stop_token)
 mw::E<void> Scheduler::runLoop(std::stop_token stop_token)
 {
     const auto initial_due = Clock::now();
+    std::mt19937 random_engine(std::random_device{}());
     for(const auto& entry : services)
     {
-        queue.push({entry.second.get(), initial_due});
+        const auto interval = entry.second->config.interval;
+        std::uniform_int_distribution<Clock::duration::rep> offset(
+            0, interval.count() - 1);
+        queue.push({entry.second.get(),
+                    initial_due + Clock::duration(offset(random_engine))});
     }
     while(!stop_token.stop_requested())
     {
diff --git a/tests/scheduler_test.cpp b/tests/scheduler_test.cpp
index 1c1f6e3..1017acf 100644
--- a/tests/scheduler_test.cpp
+++ b/tests/scheduler_test.cpp
@@ -128,7 +128,7 @@ private:
 };
 
 ServiceConfig serviceConfig(const std::string& id,
-                            Scheduler::Clock::duration interval = 1h)
+                            Scheduler::Clock::duration interval = 100ms)
 {
     return {id, "Display " + id, "Description", TcpEndpoint{"localhost", 80},
             1s, interval, "https://example.invalid"};