Functionality in main Cron class.

This commit is contained in:
Per Malmberg 2018-03-10 23:42:00 +01:00
parent 20667ae3c6
commit 0db05ac71b
10 changed files with 161 additions and 21 deletions

View File

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

View File

@ -1,14 +1,29 @@
#include <functional> #include <functional>
#include "Cron.h" #include "Cron.h"
bool libcron::Cron::add_schedule(const std::string &schedule, std::function<void()> work) namespace libcron
{ {
auto cron = CronData::create(schedule);
bool res = cron.is_valid(); bool libcron::Cron::add_schedule(const std::string& schedule, std::function<void()> work)
if (res)
{ {
items.emplace(Task(CronSchedule(cron), std::move(work))); auto cron = CronData::create(schedule);
bool res = cron.is_valid();
if (res)
{
CronSchedule s(cron);
Task t(std::move(s), std::move(work));
if (t.calculate_next())
{
items.emplace(t);
}
}
return res;
} }
return res; bool libcron::Cron::has_expired_task(const std::chrono::system_clock::time_point now) const
} {
return !items.empty() && items.top().is_expired(now);
}
}

View File

@ -10,9 +10,17 @@ namespace libcron
class Cron class Cron
{ {
public: public:
bool add_schedule(const std::string& schedule, std::function<void()> work); bool add_schedule(const std::string& schedule, std::function<void()> work);
private:
std::priority_queue<Task> items{}; size_t count() const
{
return items.size();
}
bool has_expired_task(std::chrono::system_clock::time_point now = std::chrono::system_clock::now()) const;
private:
std::priority_queue<Task> items{};
}; };
} }

View File

@ -10,8 +10,8 @@ namespace libcron
class CronSchedule class CronSchedule
{ {
public: public:
explicit CronSchedule(CronData data) explicit CronSchedule(CronData& data)
: data(std::move(data)) : data(data)
{ {
} }
@ -37,7 +37,6 @@ namespace libcron
return dt; return dt;
} }
private: private:
CronData data; CronData data;
}; };

17
libcron/Task.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "Task.h"
namespace libcron
{
bool Task::calculate_next(std::chrono::system_clock::time_point from)
{
auto result = schedule.calculate_from(from);
auto res = std::get<0>(result);
if(res)
{
next_schedule = std::get<1>(result);
}
return res;
}
}

View File

@ -3,6 +3,7 @@
#include <functional> #include <functional>
#include "CronData.h" #include "CronData.h"
#include "CronSchedule.h" #include "CronSchedule.h"
#include <chrono>
namespace libcron namespace libcron
{ {
@ -11,7 +12,7 @@ namespace libcron
public: public:
Task(CronSchedule schedule, std::function<void()> task) Task(CronSchedule schedule, std::function<void()> task)
: schedule(std::move(schedule))//, task(std::move(task)) : schedule(std::move(schedule)), task(std::move(task))
{ {
} }
@ -19,13 +20,21 @@ 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 operator<(const Task& other) const bool operator<(const Task& other) const
{ {
return false; return next_schedule < other.next_schedule;
}
bool is_expired(std::chrono::system_clock::time_point now = std::chrono::system_clock::now()) const
{
return now >= next_schedule;
} }
private: private:
CronSchedule schedule; CronSchedule schedule;
//std::function<void()> task; std::chrono::system_clock::time_point next_schedule;
std::function<void()> task;
}; };
} }

View File

@ -12,7 +12,7 @@ include_directories(
add_executable( add_executable(
${PROJECT_NAME} ${PROJECT_NAME}
test.cpp CronDataTest.cpp
CronScheduleTest.cpp) CronScheduleTest.cpp CronTest.cpp)
target_link_libraries(${PROJECT_NAME} libcron) target_link_libraries(${PROJECT_NAME} libcron)

View File

@ -178,6 +178,6 @@ SCENARIO("Multiple calculations")
SCENARIO("Unable to calculate time point") SCENARIO("Unable to calculate time point")
{ {
// TODO: Find a // TODO: Find a schedule that is unsolvable.
//REQUIRE_FALSE(test("0 0 0 1 1 0", DT(2021_y / 12 / 15), DT(2022_y / 1 / 1))); //REQUIRE_FALSE(test("0 0 0 1 1 0", DT(2021_y / 12 / 15), DT(2022_y / 1 / 1)));
} }

92
test/CronTest.cpp Normal file
View File

@ -0,0 +1,92 @@
#include <catch.hpp>
#include <libcron/Cron.h>
#include <thread>
using namespace libcron;
using namespace std::chrono;
std::string create_schedule_expiring_in(hours h, minutes m, seconds s)
{
auto now = system_clock::now() + h + m + s;
auto dt = CronSchedule::to_calendar_time(now);
std::string res = "";
res += std::to_string(dt.sec) + " ";
res += std::to_string(dt.min) + " ";
res += std::to_string(dt.hour) + " * * *";
return res;
}
SCENARIO("Adding a task")
{
GIVEN("A Cron instance with no task")
{
Cron c;
THEN("Starts with no task")
{
REQUIRE(c.count() == 0);
}
WHEN("Adding a task that runs every second")
{
REQUIRE(c.add_schedule("* * * * * *",
[]()
{
return;
})
);
THEN("Count is 1 and task was not expired two seconds ago")
{
REQUIRE(c.count() == 1);
REQUIRE_FALSE(c.has_expired_task(system_clock::now() - 2s));
}
AND_THEN("Task is expired when calculating based on current time")
{
THEN("Task is expired")
{
REQUIRE(c.has_expired_task());
}
}
}
}
}
SCENARIO("Adding a task that expires in the future")
{
GIVEN("A Cron instance with task expiring in 3 seconds")
{
Cron c;
REQUIRE(c.add_schedule(create_schedule_expiring_in(hours{0}, minutes{0}, seconds{3}),
[]()
{
return;
})
);
THEN("Not yet expired")
{
REQUIRE_FALSE(c.has_expired_task());
}
AND_WHEN("When waiting one second")
{
std::this_thread::sleep_for(1s);
THEN("Task has not yet expired")
{
REQUIRE_FALSE(c.has_expired_task());
}
}
AND_WHEN("When waiting three seconds")
{
std::this_thread::sleep_for(3s);
THEN("Task has expired")
{
REQUIRE(c.has_expired_task());
}
}
}
}