Skip to content

Commit 6421502

Browse files
committed
Absolute time scheduling logic updated
1 parent 3d099c8 commit 6421502

3 files changed

Lines changed: 82 additions & 80 deletions

File tree

Launcher.cpp

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
#include "Launcher.h"
2+
#include <inttypes.h>
23

34
namespace WPEFramework {
45

6+
ENUM_CONVERSION_BEGIN(Plugin::Launcher::mode)
7+
8+
{ Plugin::Launcher::mode::RELATIVE, _TXT("relative") },
9+
{ Plugin::Launcher::mode::ABSOLUTE, _TXT("absolute") },
10+
{ Plugin::Launcher::mode::ABSOLUTE_WITH_INTERVAL, _TXT("absolute_with_interval") },
11+
12+
ENUM_CONVERSION_END(Plugin::Launcher::mode)
13+
;
514
namespace Plugin {
615

716
SERVICE_REGISTRATION(Launcher, 1, 0);
@@ -70,7 +79,7 @@ SERVICE_REGISTRATION(Launcher, 1, 0);
7079
{
7180
Time time;
7281
Time interval;
73-
bool absolute = false;
82+
mode timeMode = RELATIVE;
7483
string message;
7584
Config config;
7685

@@ -84,7 +93,7 @@ SERVICE_REGISTRATION(Launcher, 1, 0);
8493

8594
if (config.ScheduleTime.IsSet() == true) {
8695

87-
absolute = config.ScheduleTime.Absolute.Value();
96+
timeMode = config.ScheduleTime.Mode.Value();
8897

8998
time = Time(config.ScheduleTime.Time.Value());
9099
if (time.IsValid() != true) {
@@ -102,20 +111,26 @@ SERVICE_REGISTRATION(Launcher, 1, 0);
102111
if (_activity->IsOperational() == false) {
103112
// Well if we where able to parse the parameters (if needed) we are ready to start it..
104113
_observer.Register(&_notification);
114+
Core::Time scheduledTime;
105115
if (time.IsValid() == true) {
106-
if (absolute == true) {
107-
//Schedule Job at absolute timing
108-
Core::Time scheduledTime = FindAbsoluteTimeForSchedule(time, interval);
109-
PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity);
110-
}
111-
else { //Schedule Job at relative timing
112-
Core::Time scheduledTime(Core::Time::Now();
113-
uint64_t timeValueToTrigger = ((((time.Hour() != (uint8_t)(~0)) ? time.Hour(): 0) * MinutesPerHour +
114-
((time.Minute() != (uint8_t)(~0)) ? time.Minute(): 0)) * SecondsPerMinute + time.Second()) * MilliSecondsPerSecond;
116+
if (timeMode == RELATIVE) { //Schedule Job at relative timing
117+
scheduledTime = Core::Time::Now();
118+
119+
uint64_t timeValueToTrigger = ((((time.Hours() != (uint8_t)(~0)) ? time.Hours(): 0) * MinutesPerHour +
120+
((time.Minutes() != (uint8_t)(~0)) ? time.Minutes(): 0)) * SecondsPerMinute + time.Seconds()) * MilliSecondsPerSecond;
115121
scheduledTime.Add(timeValueToTrigger);
116122

117-
PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity);
118123
}
124+
else {
125+
//Schedule Job at absolute timing
126+
if (timeMode == ABSOLUTE_WITH_INTERVAL) {
127+
scheduledTime = FindAbsoluteTimeForSchedule(time, interval);
128+
}
129+
else {
130+
scheduledTime = FindAbsoluteTimeForSchedule(time, Time());
131+
}
132+
}
133+
PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity);
119134
}
120135
else {
121136
PluginHost::WorkerPool::Instance().Submit(_activity);
@@ -189,63 +204,40 @@ void Launcher::Update(const ProcessObserver::Info& info)
189204
}
190205
}
191206

192-
Core::Time Launcher::FindAbsoluteTimeForSchedule(const Time absoluteTime, const Time interval) {
207+
Core::Time Launcher::FindAbsoluteTimeForSchedule(const Time& absoluteTime, const Time& interval) {
208+
Core::Time startTime = Core::Time::Now();
209+
// Go to a first viable start time (compared to the current time, in seconds)
210+
Core::Time slotTime = Core::Time(startTime.Year(), startTime.Month(), startTime.Day(),
211+
(absoluteTime.HasHours() ? absoluteTime.Hours() : startTime.Hours()),
212+
(absoluteTime.HasMinutes() ? absoluteTime.Minutes() : startTime.Minutes()),
213+
absoluteTime.Seconds(), 0, false);
193214

194-
Core::Time scheduledTime;
195-
Core::Time currentTime(Core::Time::Now());
196-
197-
uint64_t absoluteTimeInMilliSeconds = 0;
198-
uint64_t currentTimeInMilliSeconds = 0;
199-
200-
if (!absoluteTime.HasHours()) { //Hour is don't care condition, so schedule based on the MM.SS
201-
uint64_t nextScheduleTimeInMilliSeconds = 0;
202-
uint64_t timeLimitInMilliSeconds = 0;
203-
if (!absoluteTime.HasMinutes()) { //Minute is don't care condition, so schedule based on the SS
204-
absoluteTimeInMilliSeconds = (absoluteTime.Second() * MilliSecondsPerSecond);
205-
currentTimeInMilliSeconds = (currentTime.Seconds() * MilliSecondsPerSecond);
206-
timeLimitInMilliSeconds = (SecondsPerMinute * MilliSecondsPerSecond);
207-
}
208-
else {
209-
absoluteTimeInMilliSeconds = ((absoluteTime.Minute() * SecondsPerMinute) + absoluteTime.Second()) * MilliSecondsPerSecond;
210-
currentTimeInMilliSeconds = ((currentTime.Minutes() * SecondsPerMinute) + currentTime.Seconds()) * MilliSecondsPerSecond;
211-
timeLimitInMilliSeconds = MinutesPerHour * SecondsPerMinute * MilliSecondsPerSecond;
212-
}
213-
if (currentTimeInMilliSeconds < absoluteTimeInMilliSeconds) { //Time is not reached
214-
nextScheduleTimeInMilliSeconds = absoluteTimeInMilliSeconds - currentTimeInMilliSeconds;
215-
}
216-
else {
217-
nextScheduleTimeInMilliSeconds = (timeLimitInMilliSeconds - currentTimeInMilliSeconds) + absoluteTimeInMilliSeconds;
215+
if (interval.IsValid() == false) {
216+
if (slotTime < startTime) {
217+
uint32_t jump (absoluteTime.HasHours() ? HoursPerDay * MinutesPerHour * SecondsPerMinute : (absoluteTime.HasMinutes() ? MinutesPerHour * SecondsPerMinute : SecondsPerMinute));
218+
slotTime.Add(jump * 100);
218219
}
219-
scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds);
220220
}
221221
else {
222-
absoluteTimeInMilliSeconds = ((absoluteTime.Hour() * MinutesPerHour + absoluteTime.Minute()) * SecondsPerMinute + absoluteTime.Second()) * MilliSecondsPerSecond;
223-
currentTimeInMilliSeconds = ((currentTime.Hours() * MinutesPerHour + currentTime.Minutes()) * SecondsPerMinute + currentTime.Seconds()) * MilliSecondsPerSecond;
224-
if (currentTimeInMilliSeconds < absoluteTimeInMilliSeconds) { //Time is not reached
225-
scheduledTime = currentTime.Add(absoluteTimeInMilliSeconds - currentTimeInMilliSeconds);
226-
}
227-
else { //Time is already hit, find next suitable time
228-
uint64_t nextScheduleTimeInMilliSeconds = 0;
229-
if (interval.IsValid() == true) {
230-
uint64_t intervalTimeInMilliSeconds = ((((interval.Hour() != ~0) ? interval.Hour(): 0) * MinutesPerHour +
231-
((interval.Minute() != ~0) ? interval.Minute(): 0)) * SecondsPerMinute + interval.Second()) * MilliSecondsPerSecond;
232-
nextScheduleTimeInMilliSeconds = absoluteTimeInMilliSeconds + intervalTimeInMilliSeconds;
233-
do {
234-
if (currentTimeInMilliSeconds < nextScheduleTimeInMilliSeconds) {
235-
break;
236-
}
237-
nextScheduleTimeInMilliSeconds += intervalTimeInMilliSeconds;
238-
} while(1);
239-
scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds - currentTimeInMilliSeconds);
240-
}
241-
else {
242-
uint64_t timeLimitInMilliSeconds = (((HoursPerDay * MinutesPerHour) * SecondsPerMinute) * MilliSecondsPerSecond);
243-
nextScheduleTimeInMilliSeconds = (timeLimitInMilliSeconds - currentTimeInMilliSeconds) + absoluteTimeInMilliSeconds;
244-
scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds);
245-
}
222+
if (slotTime >= startTime) {
223+
uint32_t jump (absoluteTime.HasHours() ? HoursPerDay * MinutesPerHour * SecondsPerMinute : (absoluteTime.HasMinutes() ? MinutesPerHour * SecondsPerMinute : SecondsPerMinute));
224+
225+
// Go back the biggest chunk of the absoluteTime
226+
slotTime.Sub(jump * 100);
227+
}
228+
uint32_t intervalJump = ( (interval.HasHours() ? interval.Hours() * MinutesPerHour * SecondsPerMinute : 0) +
229+
(interval.HasMinutes() ? interval.Minutes() * SecondsPerMinute : 0) +
230+
interval.Seconds() ) * 100;
231+
232+
ASSERT (intervalJump != 0);
233+
234+
// Now increment with the intervall till we reach a valid point
235+
while (slotTime < startTime) {
236+
slotTime.Add(intervalJump);
246237
}
247238
}
248-
return scheduledTime;
239+
240+
return slotTime;
249241
}
250242

251243
} //namespace Plugin

Launcher.h

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ class Launcher : public PluginHost::IPlugin {
1212
Launcher(const Launcher&) = delete;
1313
Launcher& operator=(const Launcher&) = delete;
1414

15+
public:
16+
enum mode {
17+
RELATIVE,
18+
ABSOLUTE,
19+
ABSOLUTE_WITH_INTERVAL
20+
};
21+
1522
class ProcessObserver {
1623
private:
1724
ProcessObserver(const ProcessObserver&) = delete;
@@ -300,26 +307,26 @@ class Launcher : public PluginHost::IPlugin {
300307
public:
301308
Schedule()
302309
: Core::JSON::Container()
303-
, Absolute(false)
310+
, Mode(RELATIVE)
304311
, Time()
305312
, Interval() {
306-
Add(_T("absolute"), &Absolute);
313+
Add(_T("mode"), &Mode);
307314
Add(_T("time"), &Time);
308315
Add(_T("interval"), &Interval);
309316
}
310317
Schedule(const Schedule& copy)
311318
: Core::JSON::Container()
312-
, Absolute(copy.Absolute)
319+
, Mode(copy.Mode)
313320
, Time(copy.Time)
314321
, Interval(copy.Interval) {
315-
Add(_T("absolute"), &Absolute);
322+
Add(_T("mode"), &Mode);
316323
Add(_T("time"), &Time);
317324
Add(_T("interval"), &Interval);
318325
}
319326
~Schedule() {
320327
}
321328
public:
322-
Core::JSON::Boolean Absolute;
329+
Core::JSON::EnumType<mode> Mode;
323330
Core::JSON::String Time;
324331
Core::JSON::String Interval;
325332
};
@@ -348,7 +355,7 @@ class Launcher : public PluginHost::IPlugin {
348355
Schedule ScheduleTime;
349356
};
350357

351-
private:
358+
private:
352359
static constexpr uint32_t MilliSecondsPerSecond = 1000;
353360
static constexpr uint32_t SecondsPerMinute = 60;
354361
static constexpr uint32_t MinutesPerHour = 60;
@@ -384,9 +391,9 @@ class Launcher : public PluginHost::IPlugin {
384391
bool HasHours() const { return (_hour < HoursPerDay); }
385392
bool HasMinutes() const { return (_minute < MinutesPerHour); }
386393
bool HasSeconds() const { return (_second < SecondsPerMinute); }
387-
uint8_t Hour() const { return _hour; }
388-
uint8_t Minute() const { return _minute; }
389-
uint8_t Second() const { return _second; }
394+
uint8_t Hours() const { return _hour; }
395+
uint8_t Minutes() const { return _minute; }
396+
uint8_t Seconds() const { return _second; }
390397

391398
private:
392399
bool Parse(const string& time) {
@@ -522,14 +529,16 @@ class Launcher : public PluginHost::IPlugin {
522529
_hasRun = true;
523530
// Check if the process is not active, no need to reschedule the same job again.
524531
if (_process.IsActive() == false) {
532+
533+
Core::Time currentTime(Core::Time::Now());
525534
_process.Launch(_options, &_pid);
526535
}
527536

528537
if (_interval.IsValid() == true) {
529538
// Reschedule our next launch point...
530539
Core::Time scheduledTime(Core::Time::Now());
531-
uint64_t intervalTime = ((((_interval.Hour() != (uint8_t)(~0)) ? _interval.Hour(): 0) * MinutesPerHour +
532-
((_interval.Minute() != (uint8_t)(~0)) ? _interval.Minute():0)) * SecondsPerMinute + _interval.Second()) * MilliSecondsPerSecond;
540+
uint64_t intervalTime = ((((_interval.Hours() != (uint8_t)(~0)) ? _interval.Hours(): 0) * MinutesPerHour +
541+
((_interval.Minutes() != (uint8_t)(~0)) ? _interval.Minutes():0)) * SecondsPerMinute + _interval.Seconds()) * MilliSecondsPerSecond;
533542
scheduledTime.Add(intervalTime);
534543
PluginHost::WorkerPool::Instance().Schedule(scheduledTime,Core::ProxyType<Core::IDispatch>(*this));
535544
}
@@ -595,7 +604,7 @@ class Launcher : public PluginHost::IPlugin {
595604
private:
596605
void Update(const ProcessObserver::Info& info);
597606
bool Execute();
598-
Core::Time FindAbsoluteTimeForSchedule(const Time absoluteTime, const Time interval);
607+
Core::Time FindAbsoluteTimeForSchedule(const Time& absoluteTime, const Time& interval);
599608

600609
private:
601610
PluginHost::IShell* _service;

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ Plugin to "Launch" linux applications and scripts
6969
{ "option": "-h"}
7070
],
7171
"schedule": {
72-
"absolute": false,
72+
"mode": 0,
7373
"time": "06:04.10"
7474
}
7575
}
7676
```
7777

7878
Note:
79-
1. If field "absolute" is false or not set, it will treat the time as relative
79+
1. If field "mode" is zero or not set, it will treat the time as relative
8080
2. If relative time value is "00:00.00"/invalid format/not set, the launcher will ignore the given time and launch the application at the launcher activation time itself.
8181
3. If time format given is
8282
a. "XX", treat it as SS
@@ -93,7 +93,7 @@ Note:
9393
{ "option": "-h"}
9494
],
9595
"schedule": {
96-
"absolute": true,
96+
"mode": 1,
9797
"time": "06:04.10"
9898
}
9999
}
@@ -121,7 +121,7 @@ Note:
121121
{ "option": "-h"}
122122
],
123123
"schedule": {
124-
"absolute": false,
124+
"mode": 2,
125125
"time": "06:04.10",
126126
"interval": "00:40.10"
127127
}
@@ -130,8 +130,9 @@ Note:
130130

131131
Note:
132132
1. If interval value is "00:00.00"/invalid format/not set, the launcher will treat it as invalid value and ignore the interval time settings.
133-
2. If absolute time given is less than the current time and interval is set, it will identify next matching time and schedule application launch to that time.
133+
2. If mode is 2 (absolute with interval) and interval is set, it will identify next matching time and schedule application launch to that time.
134134
i.e, if the absolute time given is 04:00:00, current time is 05:10:00 and interval is 00:30:00, then next scheduling time will be 05:30:00 (will be identified from the next intervals - 04:30:00, 05:00:00, 05:30:00)
135+
3. If mode is 0(relative) or 1(absolute), the interval time will be taken only for the subsequent scheduling
135136

136137
# How to launch multiple scripts/applcations
137138

0 commit comments

Comments
 (0)