scheduler canceling, sessiion query, didn't test yet!
This commit is contained in:
parent
544db92b6e
commit
5d765958e5
15 changed files with 166 additions and 21 deletions
|
@ -7,6 +7,7 @@ set(HEADERS
|
|||
route.h
|
||||
scheduler.h
|
||||
function.h
|
||||
record.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
|
@ -15,6 +16,7 @@ set(SOURCES
|
|||
route.cpp
|
||||
scheduler.cpp
|
||||
function.cpp
|
||||
record.cpp
|
||||
)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})
|
||||
|
|
18
taskmanager/record.cpp
Normal file
18
taskmanager/record.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
//SPDX-FileCopyrightText: 2024 Yury Gubich <blue@macaw.me>
|
||||
//SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "record.h"
|
||||
|
||||
TM::Record::Record (ID id, const Task& task, Time time):
|
||||
id(id),
|
||||
task(task),
|
||||
time(time)
|
||||
{}
|
||||
|
||||
bool TM::Record::operator < (const Record& other) const {
|
||||
return time < other.time;
|
||||
}
|
||||
|
||||
bool TM::Record::operator > (const Record& other) const {
|
||||
return time > other.time;
|
||||
}
|
26
taskmanager/record.h
Normal file
26
taskmanager/record.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//SPDX-FileCopyrightText: 2024 Yury Gubich <blue@macaw.me>
|
||||
//SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
|
||||
namespace TM {
|
||||
class Record {
|
||||
public:
|
||||
using Time = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
using Task = std::function<void()>;
|
||||
using ID = uint64_t;
|
||||
|
||||
Record(ID id, const Task& task, Time time);
|
||||
|
||||
ID id;
|
||||
Task task;
|
||||
Time time;
|
||||
|
||||
bool operator > (const Record& other) const;
|
||||
bool operator < (const Record& other) const;
|
||||
};
|
||||
}
|
|
@ -3,13 +3,17 @@
|
|||
|
||||
#include "scheduler.h"
|
||||
|
||||
const TM::Record::ID TM::Scheduler::none = 0;
|
||||
|
||||
TM::Scheduler::Scheduler (std::weak_ptr<Manager> manager):
|
||||
queue(),
|
||||
scheduled(),
|
||||
manager(manager),
|
||||
mutex(),
|
||||
cond(),
|
||||
thread(nullptr),
|
||||
running(false)
|
||||
running(false),
|
||||
idCounter(TM::Scheduler::none)
|
||||
{}
|
||||
|
||||
TM::Scheduler::~Scheduler () {
|
||||
|
@ -50,28 +54,39 @@ void TM::Scheduler::loop () {
|
|||
|
||||
Time currentTime = std::chrono::steady_clock::now();
|
||||
while (!queue.empty()) {
|
||||
Time nextScheduledTime = queue.top().first;
|
||||
Time nextScheduledTime = queue.top().time;
|
||||
if (nextScheduledTime > currentTime) {
|
||||
cond.wait_until(lock, nextScheduledTime);
|
||||
break;
|
||||
}
|
||||
|
||||
Record task = queue.pop();
|
||||
Record record = queue.pop();
|
||||
std::size_t count = scheduled.erase(record.id);
|
||||
if (count == 0) //it means this record has been cancelled, no need to execute it
|
||||
continue;
|
||||
|
||||
lock.unlock();
|
||||
std::shared_ptr<Manager> mngr = manager.lock();
|
||||
if (mngr)
|
||||
mngr->schedule(std::move(task.second));
|
||||
mngr->schedule(std::make_unique<Function>(record.task));
|
||||
|
||||
lock.lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TM::Scheduler::schedule (const std::function<void()>& task, Delay delay) {
|
||||
TM::Record::ID TM::Scheduler::schedule (const Task& task, Delay delay) {
|
||||
std::unique_lock lock(mutex);
|
||||
Time time = std::chrono::steady_clock::now() + delay;
|
||||
queue.emplace(time, std::make_unique<Function>(task));
|
||||
queue.emplace(++idCounter, task, time);
|
||||
scheduled.emplace(idCounter);
|
||||
|
||||
lock.unlock();
|
||||
cond.notify_one();
|
||||
|
||||
return idCounter;
|
||||
}
|
||||
|
||||
bool TM::Scheduler::cancel (Record::ID id) {
|
||||
return scheduled.erase(id) != 0; //not to mess with the queue, here we just mark it as not scheduled
|
||||
} //and when the time comes it will be just discarded
|
||||
|
|
|
@ -6,43 +6,47 @@
|
|||
#include <memory>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <set>
|
||||
|
||||
#include "manager.h"
|
||||
#include "function.h"
|
||||
#include "record.h"
|
||||
#include "utils/helpers.h"
|
||||
|
||||
namespace TM {
|
||||
class Scheduler {
|
||||
public:
|
||||
using Delay = std::chrono::milliseconds;
|
||||
using Time = Record::Time;
|
||||
using Task = Record::Task;
|
||||
|
||||
Scheduler (std::weak_ptr<Manager> manager);
|
||||
~Scheduler ();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void schedule(const std::function<void()>& task, Delay delay);
|
||||
void start ();
|
||||
void stop ();
|
||||
Record::ID schedule (const Task& task, Delay delay);
|
||||
bool cancel (Record::ID id);
|
||||
|
||||
static const Record::ID none;
|
||||
|
||||
private:
|
||||
void loop();
|
||||
void loop ();
|
||||
|
||||
private:
|
||||
using Task = std::unique_ptr<Function>;
|
||||
using Time = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
using Record = std::pair<Time, Task>;
|
||||
|
||||
PriorityQueue<
|
||||
Record,
|
||||
std::vector<Record>,
|
||||
FirstGreater<Record>
|
||||
std::greater<>
|
||||
> queue;
|
||||
std::set<Record::ID> scheduled;
|
||||
std::weak_ptr<Manager> manager;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cond;
|
||||
std::unique_ptr<std::thread> thread;
|
||||
bool running;
|
||||
Record::ID idCounter;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue