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"};