IQRF Gateway Daemon
Scheduler.h
Go to the documentation of this file.
1 
17 #pragma once
18 
19 #include "JsonUtils.h"
20 #include "TaskQueue.h"
21 #include "IScheduler.h"
22 #include <string>
23 #include <chrono>
24 #include <map>
25 #include <memory>
26 
27 class ScheduleRecord;
28 
87 class Scheduler : public IScheduler
88 {
89 public:
90  typedef long TaskHandle;
91 
92  Scheduler();
93  virtual ~Scheduler();
94 
95  void start() override;
96  void stop() override;
97 
98  void registerMessageHandler(const std::string& clientId, TaskHandlerFunc fun) override;
99  void unregisterMessageHandler(const std::string& clientId) override;
100 
101  std::vector<std::string> getMyTasks(const std::string& clientId) const override;
102  std::string getMyTask(const std::string& clientId, const TaskHandle& hndl) const override;
103 
104  TaskHandle scheduleTaskAt(const std::string& clientId, const std::string& task, const std::chrono::system_clock::time_point& tp) override;
105  TaskHandle scheduleTaskPeriodic(const std::string& clientId, const std::string& task, const std::chrono::seconds& sec,
106  const std::chrono::system_clock::time_point& tp) override;
107 
108  void removeAllMyTasks(const std::string& clientId) override;
109  void removeTask(const std::string& clientId, TaskHandle hndl) override;
110  void removeTasks(const std::string& clientId, std::vector<TaskHandle> hndls) override;
111 
116  void updateConfiguration(const rapidjson::Value& cfg);
117 
118 private:
119  int handleScheduledRecord(const ScheduleRecord& record);
120 
121  TaskHandle addScheduleRecordUnlocked(std::shared_ptr<ScheduleRecord>& record);
122  TaskHandle addScheduleRecord(std::shared_ptr<ScheduleRecord>& record);
123  void addScheduleRecords(std::vector<std::shared_ptr<ScheduleRecord>>& records);
124 
125  void removeScheduleRecordUnlocked(std::shared_ptr<ScheduleRecord>& record);
126  void removeScheduleRecord(std::shared_ptr<ScheduleRecord>& record);
127  void removeScheduleRecords(std::vector<std::shared_ptr<ScheduleRecord>>& records);
128 
130  TaskQueue<ScheduleRecord>* m_dpaTaskQueue;
131 
132  std::map<std::string, TaskHandlerFunc> m_messageHandlers;
133  std::mutex m_messageHandlersMutex;
134 
135  // Scheduled tasks by time contains [time_point, ScheduleRecords] pairs.
136  // When the time_point is reached, the task is fired and removed. Another pair is added with the next time_point
137  // generated from required time matrice
138  std::multimap<std::chrono::system_clock::time_point, std::shared_ptr<ScheduleRecord>> m_scheduledTasksByTime;
139  bool m_scheduledTaskPushed;
140  mutable std::mutex m_scheduledTasksMutex;
141 
142  std::thread m_timerThread;
143  std::atomic_bool m_runTimerThread;
144  std::mutex m_conditionVariableMutex;
145  std::condition_variable m_conditionVariable;
146  void timer();
147  void nextWakeupAndUnlock(std::chrono::system_clock::time_point& timePoint);
148 
149  std::map<TaskHandle, std::shared_ptr<ScheduleRecord>> m_scheduledTasksByHandle;
150 
151 };
152 
156 public:
157  ScheduleRecord() = delete;
158  ScheduleRecord(const std::string& clientId, const std::string& task, const std::chrono::system_clock::time_point& tp);
159  ScheduleRecord(const std::string& clientId, const std::string& task, const std::chrono::seconds& sec,
160  const std::chrono::system_clock::time_point& tp);
161  ScheduleRecord(const std::string& rec);
162  ScheduleRecord(const rapidjson::Value& rec);
163 
164  Scheduler::TaskHandle getTaskHandle() const { return m_taskHandle; }
165  std::chrono::system_clock::time_point getNext(const std::chrono::system_clock::time_point& actualTimePoint, const std::tm& actualTime);
166  bool verifyTimePattern(const std::tm& actualTime) const;
167  const std::string& getTask() const { return m_task; }
168  const std::string& getClientId() const { return m_clientId; }
169 
170  static std::string asString(const std::chrono::system_clock::time_point& tp);
171  static void getTime(std::chrono::system_clock::time_point& timePoint, std::tm& timeStr);
172 
173 private:
174  //These special time specification "nicknames" which replace the 5 initial time and date fields,
175  //and are prefixed with the '@' character, are supported :
176  //@reboot : Run once after reboot.
177  // @yearly : Run once a year, ie. "0 0 0 0 1 1 *".
178  // @annually : Run once a year, ie. "0 0 0 0 1 1 *".
179  // @monthly : Run once a month, ie. "0 0 0 0 1 * *".
180  // @weekly : Run once a week, ie. "0 0 0 * * * 0".
181  // @daily : Run once a day, ie. "0 0 0 * * * *".
182  // @hourly : Run once an hour, ie. "0 0 * * * * *".
183  // @minutely : Run once a minute, ie. "0 * * * * * *".
184  std::string solveNickname(const std::string& timeSpec);
185 
186  //Change handle it if duplicit detected by Scheduler
187  void shuffleHandle(); //change handle it if duplicit exists
188  //The only method can do it
189  friend void shuffleDuplicitHandle(ScheduleRecord& rec);
190  void init();
191  int parseItem(const std::string& item, int mnm, int mxm, std::vector<int>& vec, int offset = 0);
192  bool verifyTimePattern(int cval, const std::vector<int>& tvalV) const;
193  std::string m_task;
194  std::string m_clientId;
195 
196  //multi record
197  std::vector<int> m_vsec;
198  std::vector<int> m_vmin;
199  std::vector<int> m_vhour;
200  std::vector<int> m_vmday;
201  std::vector<int> m_vmon;
202  std::vector<int> m_vyear;
203  std::vector<int> m_vwday;
204 
205  //explicit timing
206  bool m_exactTime = false;
207  bool m_periodic = false;
208  bool m_started = false;
209  std::chrono::seconds m_period;
210  std::chrono::system_clock::time_point m_startTime;
211 
212  Scheduler::TaskHandle m_taskHandle;
213 };
void removeTasks(const std::string &clientId, std::vector< TaskHandle > hndls) override
Remove tasks for client.
Definition: Scheduler.cpp:364
void removeAllMyTasks(const std::string &clientId) override
Remove all task for client.
Definition: Scheduler.cpp:342
const std::string & getTask() const
Definition: Scheduler.h:167
Tasks scheduler.
Definition: Scheduler.h:87
std::function< void(const std::string &)> TaskHandlerFunc
Task to be processed handler functional type.
Definition: IScheduler.h:38
void stop() override
Stop IScheduler instance.
Definition: Scheduler.cpp:102
long TaskHandle
Definition: Scheduler.h:90
Scheduler()
Definition: Scheduler.cpp:24
TaskHandle scheduleTaskAt(const std::string &clientId, const std::string &task, const std::chrono::system_clock::time_point &tp) override
Schedule task at time point.
Definition: Scheduler.cpp:118
void removeTask(const std::string &clientId, TaskHandle hndl) override
Remove task for client.
Definition: Scheduler.cpp:356
virtual ~Scheduler()
Definition: Scheduler.cpp:29
void start() override
Start IScheduler instance.
Definition: Scheduler.cpp:85
TaskHandle scheduleTaskPeriodic(const std::string &clientId, const std::string &task, const std::chrono::seconds &sec, const std::chrono::system_clock::time_point &tp) override
Schedule periodic task.
Definition: Scheduler.cpp:124
void registerMessageHandler(const std::string &clientId, TaskHandlerFunc fun) override
Register task handler.
Definition: Scheduler.cpp:305
void unregisterMessageHandler(const std::string &clientId) override
Unregister task handler.
Definition: Scheduler.cpp:312
IScheduler interface.
Definition: IScheduler.h:28
void updateConfiguration(const rapidjson::Value &cfg)
Update configuration.
Definition: Scheduler.cpp:44
std::string getMyTask(const std::string &clientId, const TaskHandle &hndl) const override
Get a particular tasks for a client.
Definition: Scheduler.cpp:331
Scheduler::TaskHandle getTaskHandle() const
Definition: Scheduler.h:164
Definition: Scheduler.h:155
void shuffleDuplicitHandle(ScheduleRecord &rec)
Definition: Scheduler.cpp:396
std::vector< std::string > getMyTasks(const std::string &clientId) const override
Get scheduled tasks for a client.
Definition: Scheduler.cpp:318
const std::string & getClientId() const
Definition: Scheduler.h:168