From 74e1ad4d607232907741b20922e7f7a15531195b Mon Sep 17 00:00:00 2001 From: Per Malmberg Date: Sun, 11 Mar 2018 20:09:06 +0100 Subject: [PATCH] Added the concept of a clock to Cron. --- libcron/CMakeLists.txt | 2 +- libcron/Cron.cpp | 6 +++--- libcron/Cron.h | 21 ++++++++++++++++++--- libcron/CronClock.h | 22 ++++++++++++++++++++++ libcron/CronSchedule.cpp | 2 +- libcron/Task.h | 6 +++--- test/CronTest.cpp | 2 +- 7 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 libcron/CronClock.h diff --git a/libcron/CMakeLists.txt b/libcron/CMakeLists.txt index 7287fc1..de6412a 100644 --- a/libcron/CMakeLists.txt +++ b/libcron/CMakeLists.txt @@ -17,4 +17,4 @@ add_library(${PROJECT_NAME} CronSchedule.h externals/date/date.h DateTime.h - Task.cpp) + Task.cpp CronClock.h) diff --git a/libcron/Cron.cpp b/libcron/Cron.cpp index 66ae942..e007bb6 100644 --- a/libcron/Cron.cpp +++ b/libcron/Cron.cpp @@ -13,7 +13,7 @@ namespace libcron { Task t{std::move(name), CronSchedule{cron}, std::move(work)}; - if (t.calculate_next()) + if (t.calculate_next(clock->now())) { tasks.push(t); } @@ -22,7 +22,7 @@ namespace libcron return res; } - std::chrono::system_clock::duration Cron::time_until_next(std::chrono::system_clock::time_point now) const + std::chrono::system_clock::duration Cron::time_until_next() const { system_clock::duration d{}; if (tasks.empty()) @@ -31,7 +31,7 @@ namespace libcron } else { - d = tasks.top().time_until_expiry(now); + d = tasks.top().time_until_expiry(clock->now()); } return d; diff --git a/libcron/Cron.h b/libcron/Cron.h index 2cd5431..0d50b50 100644 --- a/libcron/Cron.h +++ b/libcron/Cron.h @@ -5,13 +5,19 @@ #include #include #include "Task.h" +#include "CronClock.h" namespace libcron { class Cron { - public: + + explicit Cron(std::unique_ptr clock = std::make_unique()) + : clock(std::move(clock)) + { + } + bool add_schedule(std::string name, const std::string& schedule, std::function work); size_t count() const @@ -20,14 +26,23 @@ namespace libcron } size_t - execute_expired_tasks(std::chrono::system_clock::time_point now = std::chrono::system_clock::now()); + execute_expired_tasks() + { + return execute_expired_tasks(clock->now()); + } + + size_t + execute_expired_tasks(std::chrono::system_clock::time_point now); std::chrono::system_clock::duration - time_until_next(std::chrono::system_clock::time_point now = std::chrono::system_clock::now()) const; + time_until_next() const; + + std::shared_ptr get_clock() const { return clock; } private: // Priority queue placing smallest (i.e. nearest in time) items on top. std::priority_queue, std::greater<>> tasks{}; void print_queue(std::priority_queue, std::greater<>> queue); + std::shared_ptr clock{}; }; } \ No newline at end of file diff --git a/libcron/CronClock.h b/libcron/CronClock.h new file mode 100644 index 0000000..b833b60 --- /dev/null +++ b/libcron/CronClock.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace libcron +{ + class ICronClock + { + public: + virtual std::chrono::system_clock::time_point now() = 0; + }; + + class UTCClock + : public ICronClock + { + public: + std::chrono::system_clock::time_point now() override + { + return std::chrono::system_clock::now(); + } + }; +} \ No newline at end of file diff --git a/libcron/CronSchedule.cpp b/libcron/CronSchedule.cpp index bd50860..6e181c0 100644 --- a/libcron/CronSchedule.cpp +++ b/libcron/CronSchedule.cpp @@ -80,6 +80,6 @@ namespace libcron } } - return std::make_tuple(max_iterations > 0, max_iterations > 0 ? curr : system_clock::now()); + return std::make_tuple(max_iterations > 0, curr); } } \ No newline at end of file diff --git a/libcron/Task.h b/libcron/Task.h index 322e9e3..f44b03c 100644 --- a/libcron/Task.h +++ b/libcron/Task.h @@ -26,17 +26,17 @@ namespace libcron Task& operator=(const Task&) = default; - bool calculate_next(std::chrono::system_clock::time_point from = std::chrono::system_clock::now()); + bool calculate_next(std::chrono::system_clock::time_point from); bool operator>(const Task& other) const { return next_schedule > other.next_schedule; } - bool is_expired(std::chrono::system_clock::time_point now = std::chrono::system_clock::now()) const; + bool is_expired(std::chrono::system_clock::time_point now) const; std::chrono::system_clock::duration - time_until_expiry(std::chrono::system_clock::time_point now = std::chrono::system_clock::now()) const; + time_until_expiry(std::chrono::system_clock::time_point now) const; std::string get_name() const { diff --git a/test/CronTest.cpp b/test/CronTest.cpp index 5dde473..5e4b169 100644 --- a/test/CronTest.cpp +++ b/test/CronTest.cpp @@ -44,7 +44,7 @@ SCENARIO("Adding a task") THEN("Count is 1 and task was not expired two seconds ago") { REQUIRE(c.count() == 1); - c.execute_expired_tasks(system_clock::now() - 2s); + c.execute_expired_tasks(c.get_clock()->now() - 2s); REQUIRE_FALSE(expired); } AND_THEN("Task is expired when calculating based on current time")