Added the concept of a clock to Cron.

This commit is contained in:
Per Malmberg 2018-03-11 20:09:06 +01:00
parent be2b4424a1
commit 74e1ad4d60
7 changed files with 49 additions and 12 deletions

View File

@ -17,4 +17,4 @@ add_library(${PROJECT_NAME}
CronSchedule.h CronSchedule.h
externals/date/date.h externals/date/date.h
DateTime.h DateTime.h
Task.cpp) Task.cpp CronClock.h)

View File

@ -13,7 +13,7 @@ namespace libcron
{ {
Task t{std::move(name), CronSchedule{cron}, std::move(work)}; Task t{std::move(name), CronSchedule{cron}, std::move(work)};
if (t.calculate_next()) if (t.calculate_next(clock->now()))
{ {
tasks.push(t); tasks.push(t);
} }
@ -22,7 +22,7 @@ namespace libcron
return res; 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{}; system_clock::duration d{};
if (tasks.empty()) if (tasks.empty())
@ -31,7 +31,7 @@ namespace libcron
} }
else else
{ {
d = tasks.top().time_until_expiry(now); d = tasks.top().time_until_expiry(clock->now());
} }
return d; return d;

View File

@ -5,13 +5,19 @@
#include <queue> #include <queue>
#include <memory> #include <memory>
#include "Task.h" #include "Task.h"
#include "CronClock.h"
namespace libcron namespace libcron
{ {
class Cron class Cron
{ {
public: public:
explicit Cron(std::unique_ptr<ICronClock> clock = std::make_unique<UTCClock>())
: clock(std::move(clock))
{
}
bool add_schedule(std::string name, const std::string& schedule, std::function<void()> work); bool add_schedule(std::string name, const std::string& schedule, std::function<void()> work);
size_t count() const size_t count() const
@ -20,14 +26,23 @@ namespace libcron
} }
size_t 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 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<ICronClock> get_clock() const { return clock; }
private: private:
// Priority queue placing smallest (i.e. nearest in time) items on top. // Priority queue placing smallest (i.e. nearest in time) items on top.
std::priority_queue<Task, std::vector<Task>, std::greater<>> tasks{}; std::priority_queue<Task, std::vector<Task>, std::greater<>> tasks{};
void print_queue(std::priority_queue<Task, std::vector<Task>, std::greater<>> queue); void print_queue(std::priority_queue<Task, std::vector<Task>, std::greater<>> queue);
std::shared_ptr<ICronClock> clock{};
}; };
} }

22
libcron/CronClock.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <chrono>
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();
}
};
}

View File

@ -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);
} }
} }

View File

@ -26,17 +26,17 @@ namespace libcron
Task& operator=(const Task&) = default; 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 bool operator>(const Task& other) const
{ {
return next_schedule > other.next_schedule; 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 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 std::string get_name() const
{ {

View File

@ -44,7 +44,7 @@ SCENARIO("Adding a task")
THEN("Count is 1 and task was not expired two seconds ago") THEN("Count is 1 and task was not expired two seconds ago")
{ {
REQUIRE(c.count() == 1); REQUIRE(c.count() == 1);
c.execute_expired_tasks(system_clock::now() - 2s); c.execute_expired_tasks(c.get_clock()->now() - 2s);
REQUIRE_FALSE(expired); REQUIRE_FALSE(expired);
} }
AND_THEN("Task is expired when calculating based on current time") AND_THEN("Task is expired when calculating based on current time")