From 3d099c8c1a7c68af5b9fa7e28c967d25e4b45f42 Mon Sep 17 00:00:00 2001 From: HaseenaSainul Date: Tue, 22 Jan 2019 18:57:39 +0530 Subject: [PATCH 1/3] Absolute time scheduling functionality implemented --- Launcher.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++++---- Launcher.h | 50 ++++++++++++++++++++++----------- README.md | 40 ++++++++++++++++++++++++-- 3 files changed, 145 insertions(+), 24 deletions(-) diff --git a/Launcher.cpp b/Launcher.cpp index e8a8f78..9508190 100644 --- a/Launcher.cpp +++ b/Launcher.cpp @@ -70,6 +70,7 @@ SERVICE_REGISTRATION(Launcher, 1, 0); { Time time; Time interval; + bool absolute = false; string message; Config config; @@ -83,6 +84,8 @@ SERVICE_REGISTRATION(Launcher, 1, 0); if (config.ScheduleTime.IsSet() == true) { + absolute = config.ScheduleTime.Absolute.Value(); + time = Time(config.ScheduleTime.Time.Value()); if (time.IsValid() != true) { SYSLOG(Trace::Warning, (_T("Time format is wrong"))); @@ -99,13 +102,20 @@ SERVICE_REGISTRATION(Launcher, 1, 0); if (_activity->IsOperational() == false) { // Well if we where able to parse the parameters (if needed) we are ready to start it.. _observer.Register(&_notification); - if (time.IsValid() == true) { - Core::Time scheduledTime(Core::Time::Now()); - uint64_t timeValueToTrigger = ((time.Hour() * 60 + time.Minute()) * 60 + time.Second()) * 1000; - scheduledTime.Add(timeValueToTrigger); + if (absolute == true) { + //Schedule Job at absolute timing + Core::Time scheduledTime = FindAbsoluteTimeForSchedule(time, interval); + PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity); + } + else { //Schedule Job at relative timing + Core::Time scheduledTime(Core::Time::Now(); + uint64_t timeValueToTrigger = ((((time.Hour() != (uint8_t)(~0)) ? time.Hour(): 0) * MinutesPerHour + + ((time.Minute() != (uint8_t)(~0)) ? time.Minute(): 0)) * SecondsPerMinute + time.Second()) * MilliSecondsPerSecond; + scheduledTime.Add(timeValueToTrigger); - PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity); + PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity); + } } else { PluginHost::WorkerPool::Instance().Submit(_activity); @@ -179,6 +189,65 @@ void Launcher::Update(const ProcessObserver::Info& info) } } +Core::Time Launcher::FindAbsoluteTimeForSchedule(const Time absoluteTime, const Time interval) { + + Core::Time scheduledTime; + Core::Time currentTime(Core::Time::Now()); + + uint64_t absoluteTimeInMilliSeconds = 0; + uint64_t currentTimeInMilliSeconds = 0; + + if (!absoluteTime.HasHours()) { //Hour is don't care condition, so schedule based on the MM.SS + uint64_t nextScheduleTimeInMilliSeconds = 0; + uint64_t timeLimitInMilliSeconds = 0; + if (!absoluteTime.HasMinutes()) { //Minute is don't care condition, so schedule based on the SS + absoluteTimeInMilliSeconds = (absoluteTime.Second() * MilliSecondsPerSecond); + currentTimeInMilliSeconds = (currentTime.Seconds() * MilliSecondsPerSecond); + timeLimitInMilliSeconds = (SecondsPerMinute * MilliSecondsPerSecond); + } + else { + absoluteTimeInMilliSeconds = ((absoluteTime.Minute() * SecondsPerMinute) + absoluteTime.Second()) * MilliSecondsPerSecond; + currentTimeInMilliSeconds = ((currentTime.Minutes() * SecondsPerMinute) + currentTime.Seconds()) * MilliSecondsPerSecond; + timeLimitInMilliSeconds = MinutesPerHour * SecondsPerMinute * MilliSecondsPerSecond; + } + if (currentTimeInMilliSeconds < absoluteTimeInMilliSeconds) { //Time is not reached + nextScheduleTimeInMilliSeconds = absoluteTimeInMilliSeconds - currentTimeInMilliSeconds; + } + else { + nextScheduleTimeInMilliSeconds = (timeLimitInMilliSeconds - currentTimeInMilliSeconds) + absoluteTimeInMilliSeconds; + } + scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds); + } + else { + absoluteTimeInMilliSeconds = ((absoluteTime.Hour() * MinutesPerHour + absoluteTime.Minute()) * SecondsPerMinute + absoluteTime.Second()) * MilliSecondsPerSecond; + currentTimeInMilliSeconds = ((currentTime.Hours() * MinutesPerHour + currentTime.Minutes()) * SecondsPerMinute + currentTime.Seconds()) * MilliSecondsPerSecond; + if (currentTimeInMilliSeconds < absoluteTimeInMilliSeconds) { //Time is not reached + scheduledTime = currentTime.Add(absoluteTimeInMilliSeconds - currentTimeInMilliSeconds); + } + else { //Time is already hit, find next suitable time + uint64_t nextScheduleTimeInMilliSeconds = 0; + if (interval.IsValid() == true) { + uint64_t intervalTimeInMilliSeconds = ((((interval.Hour() != ~0) ? interval.Hour(): 0) * MinutesPerHour + + ((interval.Minute() != ~0) ? interval.Minute(): 0)) * SecondsPerMinute + interval.Second()) * MilliSecondsPerSecond; + nextScheduleTimeInMilliSeconds = absoluteTimeInMilliSeconds + intervalTimeInMilliSeconds; + do { + if (currentTimeInMilliSeconds < nextScheduleTimeInMilliSeconds) { + break; + } + nextScheduleTimeInMilliSeconds += intervalTimeInMilliSeconds; + } while(1); + scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds - currentTimeInMilliSeconds); + } + else { + uint64_t timeLimitInMilliSeconds = (((HoursPerDay * MinutesPerHour) * SecondsPerMinute) * MilliSecondsPerSecond); + nextScheduleTimeInMilliSeconds = (timeLimitInMilliSeconds - currentTimeInMilliSeconds) + absoluteTimeInMilliSeconds; + scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds); + } + } + } + return scheduledTime; +} + } //namespace Plugin } // namespace WPEFramework diff --git a/Launcher.h b/Launcher.h index 52c1938..e51e6d9 100644 --- a/Launcher.h +++ b/Launcher.h @@ -300,21 +300,26 @@ class Launcher : public PluginHost::IPlugin { public: Schedule() : Core::JSON::Container() + , Absolute(false) , Time() , Interval() { + Add(_T("absolute"), &Absolute); Add(_T("time"), &Time); Add(_T("interval"), &Interval); } Schedule(const Schedule& copy) : Core::JSON::Container() + , Absolute(copy.Absolute) , Time(copy.Time) , Interval(copy.Interval) { + Add(_T("absolute"), &Absolute); Add(_T("time"), &Time); Add(_T("interval"), &Interval); } ~Schedule() { } public: + Core::JSON::Boolean Absolute; Core::JSON::String Time; Core::JSON::String Interval; }; @@ -343,6 +348,12 @@ class Launcher : public PluginHost::IPlugin { Schedule ScheduleTime; }; +private: + static constexpr uint32_t MilliSecondsPerSecond = 1000; + static constexpr uint32_t SecondsPerMinute = 60; + static constexpr uint32_t MinutesPerHour = 60; + static constexpr uint32_t HoursPerDay = 24; + class Time { public: Time() @@ -370,9 +381,9 @@ class Launcher : public PluginHost::IPlugin { public: bool IsValid () const { return (HasSeconds() || HasMinutes() || HasHours()); } - bool HasHours() const { return (_hour < 24); } - bool HasMinutes() const { return (_minute < 60); } - bool HasSeconds() const { return (_second < 60); } + bool HasHours() const { return (_hour < HoursPerDay); } + bool HasMinutes() const { return (_minute < MinutesPerHour); } + bool HasSeconds() const { return (_second < SecondsPerMinute); } uint8_t Hour() const { return _hour; } uint8_t Minute() const { return _minute; } uint8_t Second() const { return _second; } @@ -383,25 +394,30 @@ class Launcher : public PluginHost::IPlugin { string t = time; //Get hours - uint8_t hour; + uint8_t hour = (~0); string hValue = Split(t, ":"); - status = IsValidTime(hValue, hour, 24); + if (hValue.empty() != true) { + status = IsValidTime(hValue, hour, HoursPerDay); + } if (status == true) { - - //Get minutes - uint8_t minute; + //Get minutes + uint8_t minute = (~0); string mValue = Split(t, "."); - status = IsValidTime(mValue, minute, 60); + if (mValue.empty() != true) { + status = IsValidTime(mValue, minute, MinutesPerHour); + } if (status == true) { //Store seconds - uint8_t second; + uint8_t second = (~0); string sValue = t; - status = IsValidTime(sValue, second, 60); + if (sValue.empty() != true) { + status = IsValidTime(sValue, second, SecondsPerMinute); + } if (status == true) { //Check all the time components are still valid - if ((hour > 0 && second > 0) && (minute == 0)) { + if ((hour != (~0) && second != (~0)) && (minute == (~0))) { status = false; TRACE(Trace::Information, (_T("Invalid time format"))); } @@ -416,7 +432,7 @@ class Launcher : public PluginHost::IPlugin { return status; } -private: + private: inline bool IsDigit(const string& str) { return (str.find_first_not_of( "0123456789" ) == std::string::npos); } @@ -450,7 +466,7 @@ class Launcher : public PluginHost::IPlugin { return word; } -private: + private: uint8_t _hour; uint8_t _minute; uint8_t _second; @@ -509,10 +525,11 @@ class Launcher : public PluginHost::IPlugin { _process.Launch(_options, &_pid); } - if (_interval.IsValid() == true && ((_interval.Hour() != 0) || (_interval.Minute() != 0) || (_interval.Second() != 0))) { + if (_interval.IsValid() == true) { // Reschedule our next launch point... Core::Time scheduledTime(Core::Time::Now()); - uint64_t intervalTime = ((_interval.Hour() * 60 + _interval.Minute()) * 60 + _interval.Second()) * 1000; + uint64_t intervalTime = ((((_interval.Hour() != (uint8_t)(~0)) ? _interval.Hour(): 0) * MinutesPerHour + + ((_interval.Minute() != (uint8_t)(~0)) ? _interval.Minute():0)) * SecondsPerMinute + _interval.Second()) * MilliSecondsPerSecond; scheduledTime.Add(intervalTime); PluginHost::WorkerPool::Instance().Schedule(scheduledTime,Core::ProxyType(*this)); } @@ -578,6 +595,7 @@ class Launcher : public PluginHost::IPlugin { private: void Update(const ProcessObserver::Info& info); bool Execute(); + Core::Time FindAbsoluteTimeForSchedule(const Time absoluteTime, const Time interval); private: PluginHost::IShell* _service; diff --git a/README.md b/README.md index 197ba04..3851fe9 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,9 @@ Plugin to "Launch" linux applications and scripts } ``` -### How to schedule an application/script +### How to schedule an application/script with relative time -1. Add schedule relative time information to the Launcher.json in the HH:MM.SS format (Hour:Minute.Second) +1. Add 'relative' time information to the Launcher.json in the HH:MM.SS format (Hour:Minute.Second) ``` "configuration": { "command":"du", @@ -78,6 +78,37 @@ Plugin to "Launch" linux applications and scripts Note: 1. If field "absolute" is false or not set, it will treat the time as relative 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. +3. If time format given is + a. "XX", treat it as SS + b. "XX.XX" treat it as MM.SS + +### How to schedule an application/script with absolute time + +1. Add 'absolute' time information to the Launcher.json in the HH:MM.SS format (Hour:Minute.Second) + ``` + "configuration": { + "command":"du", + "parameters": [ + { "option": "-a", "value": "/etc" }, + { "option": "-h"} + ], + "schedule": { + "absolute": true, + "time": "06:04.10" + } + } + ``` + +Note: +1. If absolute time value is invalid format/not set, the launcher will ignore the given time and launch the application at the launcher activation time itself. +2. If time format given is + a. "XX", treat it as SS, and schedule the application launch at next SSth time. i.e. if absolute time given is 25 and current time is 08:10:45, then the application will be + launched at 08:11:25 + b. "XX.XX" treat it as MM.SS, and scedule the application launch at next MM:SSth time. i.e. if absolute time given is 30.20 and current time is 08:10:45, then the application will be + launched at 09:30:20 + c. "00:00.00" treat it as midnight. +3. If absolute time given is less than the current time, it will launch the application the same time at the subsequent day. i.e, if absolute time given is 13:00:00, it will launch + the application at same time at the next day. ### How to schedule an application/script to run in an interval @@ -97,7 +128,10 @@ Note: } ``` -Note: 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. +Note: +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. +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. + 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) # How to launch multiple scripts/applcations From 6421502f7b6b18ab629f7bdd5ee80215af14ed35 Mon Sep 17 00:00:00 2001 From: HaseenaSainul Date: Wed, 23 Jan 2019 00:00:10 +0530 Subject: [PATCH 2/3] Absolute time scheduling logic updated --- Launcher.cpp | 118 ++++++++++++++++++++++++--------------------------- Launcher.h | 33 ++++++++------ README.md | 11 ++--- 3 files changed, 82 insertions(+), 80 deletions(-) diff --git a/Launcher.cpp b/Launcher.cpp index 9508190..ac766b7 100644 --- a/Launcher.cpp +++ b/Launcher.cpp @@ -1,7 +1,16 @@ #include "Launcher.h" +#include namespace WPEFramework { +ENUM_CONVERSION_BEGIN(Plugin::Launcher::mode) + + { Plugin::Launcher::mode::RELATIVE, _TXT("relative") }, + { Plugin::Launcher::mode::ABSOLUTE, _TXT("absolute") }, + { Plugin::Launcher::mode::ABSOLUTE_WITH_INTERVAL, _TXT("absolute_with_interval") }, + + ENUM_CONVERSION_END(Plugin::Launcher::mode) +; namespace Plugin { SERVICE_REGISTRATION(Launcher, 1, 0); @@ -70,7 +79,7 @@ SERVICE_REGISTRATION(Launcher, 1, 0); { Time time; Time interval; - bool absolute = false; + mode timeMode = RELATIVE; string message; Config config; @@ -84,7 +93,7 @@ SERVICE_REGISTRATION(Launcher, 1, 0); if (config.ScheduleTime.IsSet() == true) { - absolute = config.ScheduleTime.Absolute.Value(); + timeMode = config.ScheduleTime.Mode.Value(); time = Time(config.ScheduleTime.Time.Value()); if (time.IsValid() != true) { @@ -102,20 +111,26 @@ SERVICE_REGISTRATION(Launcher, 1, 0); if (_activity->IsOperational() == false) { // Well if we where able to parse the parameters (if needed) we are ready to start it.. _observer.Register(&_notification); + Core::Time scheduledTime; if (time.IsValid() == true) { - if (absolute == true) { - //Schedule Job at absolute timing - Core::Time scheduledTime = FindAbsoluteTimeForSchedule(time, interval); - PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity); - } - else { //Schedule Job at relative timing - Core::Time scheduledTime(Core::Time::Now(); - uint64_t timeValueToTrigger = ((((time.Hour() != (uint8_t)(~0)) ? time.Hour(): 0) * MinutesPerHour + - ((time.Minute() != (uint8_t)(~0)) ? time.Minute(): 0)) * SecondsPerMinute + time.Second()) * MilliSecondsPerSecond; + if (timeMode == RELATIVE) { //Schedule Job at relative timing + scheduledTime = Core::Time::Now(); + + uint64_t timeValueToTrigger = ((((time.Hours() != (uint8_t)(~0)) ? time.Hours(): 0) * MinutesPerHour + + ((time.Minutes() != (uint8_t)(~0)) ? time.Minutes(): 0)) * SecondsPerMinute + time.Seconds()) * MilliSecondsPerSecond; scheduledTime.Add(timeValueToTrigger); - PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity); } + else { + //Schedule Job at absolute timing + if (timeMode == ABSOLUTE_WITH_INTERVAL) { + scheduledTime = FindAbsoluteTimeForSchedule(time, interval); + } + else { + scheduledTime = FindAbsoluteTimeForSchedule(time, Time()); + } + } + PluginHost::WorkerPool::Instance().Schedule(scheduledTime, _activity); } else { PluginHost::WorkerPool::Instance().Submit(_activity); @@ -189,63 +204,40 @@ void Launcher::Update(const ProcessObserver::Info& info) } } -Core::Time Launcher::FindAbsoluteTimeForSchedule(const Time absoluteTime, const Time interval) { +Core::Time Launcher::FindAbsoluteTimeForSchedule(const Time& absoluteTime, const Time& interval) { + Core::Time startTime = Core::Time::Now(); + // Go to a first viable start time (compared to the current time, in seconds) + Core::Time slotTime = Core::Time(startTime.Year(), startTime.Month(), startTime.Day(), + (absoluteTime.HasHours() ? absoluteTime.Hours() : startTime.Hours()), + (absoluteTime.HasMinutes() ? absoluteTime.Minutes() : startTime.Minutes()), + absoluteTime.Seconds(), 0, false); - Core::Time scheduledTime; - Core::Time currentTime(Core::Time::Now()); - - uint64_t absoluteTimeInMilliSeconds = 0; - uint64_t currentTimeInMilliSeconds = 0; - - if (!absoluteTime.HasHours()) { //Hour is don't care condition, so schedule based on the MM.SS - uint64_t nextScheduleTimeInMilliSeconds = 0; - uint64_t timeLimitInMilliSeconds = 0; - if (!absoluteTime.HasMinutes()) { //Minute is don't care condition, so schedule based on the SS - absoluteTimeInMilliSeconds = (absoluteTime.Second() * MilliSecondsPerSecond); - currentTimeInMilliSeconds = (currentTime.Seconds() * MilliSecondsPerSecond); - timeLimitInMilliSeconds = (SecondsPerMinute * MilliSecondsPerSecond); - } - else { - absoluteTimeInMilliSeconds = ((absoluteTime.Minute() * SecondsPerMinute) + absoluteTime.Second()) * MilliSecondsPerSecond; - currentTimeInMilliSeconds = ((currentTime.Minutes() * SecondsPerMinute) + currentTime.Seconds()) * MilliSecondsPerSecond; - timeLimitInMilliSeconds = MinutesPerHour * SecondsPerMinute * MilliSecondsPerSecond; - } - if (currentTimeInMilliSeconds < absoluteTimeInMilliSeconds) { //Time is not reached - nextScheduleTimeInMilliSeconds = absoluteTimeInMilliSeconds - currentTimeInMilliSeconds; - } - else { - nextScheduleTimeInMilliSeconds = (timeLimitInMilliSeconds - currentTimeInMilliSeconds) + absoluteTimeInMilliSeconds; + if (interval.IsValid() == false) { + if (slotTime < startTime) { + uint32_t jump (absoluteTime.HasHours() ? HoursPerDay * MinutesPerHour * SecondsPerMinute : (absoluteTime.HasMinutes() ? MinutesPerHour * SecondsPerMinute : SecondsPerMinute)); + slotTime.Add(jump * 100); } - scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds); } else { - absoluteTimeInMilliSeconds = ((absoluteTime.Hour() * MinutesPerHour + absoluteTime.Minute()) * SecondsPerMinute + absoluteTime.Second()) * MilliSecondsPerSecond; - currentTimeInMilliSeconds = ((currentTime.Hours() * MinutesPerHour + currentTime.Minutes()) * SecondsPerMinute + currentTime.Seconds()) * MilliSecondsPerSecond; - if (currentTimeInMilliSeconds < absoluteTimeInMilliSeconds) { //Time is not reached - scheduledTime = currentTime.Add(absoluteTimeInMilliSeconds - currentTimeInMilliSeconds); - } - else { //Time is already hit, find next suitable time - uint64_t nextScheduleTimeInMilliSeconds = 0; - if (interval.IsValid() == true) { - uint64_t intervalTimeInMilliSeconds = ((((interval.Hour() != ~0) ? interval.Hour(): 0) * MinutesPerHour + - ((interval.Minute() != ~0) ? interval.Minute(): 0)) * SecondsPerMinute + interval.Second()) * MilliSecondsPerSecond; - nextScheduleTimeInMilliSeconds = absoluteTimeInMilliSeconds + intervalTimeInMilliSeconds; - do { - if (currentTimeInMilliSeconds < nextScheduleTimeInMilliSeconds) { - break; - } - nextScheduleTimeInMilliSeconds += intervalTimeInMilliSeconds; - } while(1); - scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds - currentTimeInMilliSeconds); - } - else { - uint64_t timeLimitInMilliSeconds = (((HoursPerDay * MinutesPerHour) * SecondsPerMinute) * MilliSecondsPerSecond); - nextScheduleTimeInMilliSeconds = (timeLimitInMilliSeconds - currentTimeInMilliSeconds) + absoluteTimeInMilliSeconds; - scheduledTime = currentTime.Add(nextScheduleTimeInMilliSeconds); - } + if (slotTime >= startTime) { + uint32_t jump (absoluteTime.HasHours() ? HoursPerDay * MinutesPerHour * SecondsPerMinute : (absoluteTime.HasMinutes() ? MinutesPerHour * SecondsPerMinute : SecondsPerMinute)); + + // Go back the biggest chunk of the absoluteTime + slotTime.Sub(jump * 100); + } + uint32_t intervalJump = ( (interval.HasHours() ? interval.Hours() * MinutesPerHour * SecondsPerMinute : 0) + + (interval.HasMinutes() ? interval.Minutes() * SecondsPerMinute : 0) + + interval.Seconds() ) * 100; + + ASSERT (intervalJump != 0); + + // Now increment with the intervall till we reach a valid point + while (slotTime < startTime) { + slotTime.Add(intervalJump); } } - return scheduledTime; + + return slotTime; } } //namespace Plugin diff --git a/Launcher.h b/Launcher.h index e51e6d9..6752f10 100644 --- a/Launcher.h +++ b/Launcher.h @@ -12,6 +12,13 @@ class Launcher : public PluginHost::IPlugin { Launcher(const Launcher&) = delete; Launcher& operator=(const Launcher&) = delete; +public: + enum mode { + RELATIVE, + ABSOLUTE, + ABSOLUTE_WITH_INTERVAL + }; + class ProcessObserver { private: ProcessObserver(const ProcessObserver&) = delete; @@ -300,26 +307,26 @@ class Launcher : public PluginHost::IPlugin { public: Schedule() : Core::JSON::Container() - , Absolute(false) + , Mode(RELATIVE) , Time() , Interval() { - Add(_T("absolute"), &Absolute); + Add(_T("mode"), &Mode); Add(_T("time"), &Time); Add(_T("interval"), &Interval); } Schedule(const Schedule& copy) : Core::JSON::Container() - , Absolute(copy.Absolute) + , Mode(copy.Mode) , Time(copy.Time) , Interval(copy.Interval) { - Add(_T("absolute"), &Absolute); + Add(_T("mode"), &Mode); Add(_T("time"), &Time); Add(_T("interval"), &Interval); } ~Schedule() { } public: - Core::JSON::Boolean Absolute; + Core::JSON::EnumType Mode; Core::JSON::String Time; Core::JSON::String Interval; }; @@ -348,7 +355,7 @@ class Launcher : public PluginHost::IPlugin { Schedule ScheduleTime; }; -private: + private: static constexpr uint32_t MilliSecondsPerSecond = 1000; static constexpr uint32_t SecondsPerMinute = 60; static constexpr uint32_t MinutesPerHour = 60; @@ -384,9 +391,9 @@ class Launcher : public PluginHost::IPlugin { bool HasHours() const { return (_hour < HoursPerDay); } bool HasMinutes() const { return (_minute < MinutesPerHour); } bool HasSeconds() const { return (_second < SecondsPerMinute); } - uint8_t Hour() const { return _hour; } - uint8_t Minute() const { return _minute; } - uint8_t Second() const { return _second; } + uint8_t Hours() const { return _hour; } + uint8_t Minutes() const { return _minute; } + uint8_t Seconds() const { return _second; } private: bool Parse(const string& time) { @@ -522,14 +529,16 @@ class Launcher : public PluginHost::IPlugin { _hasRun = true; // Check if the process is not active, no need to reschedule the same job again. if (_process.IsActive() == false) { + + Core::Time currentTime(Core::Time::Now()); _process.Launch(_options, &_pid); } if (_interval.IsValid() == true) { // Reschedule our next launch point... Core::Time scheduledTime(Core::Time::Now()); - uint64_t intervalTime = ((((_interval.Hour() != (uint8_t)(~0)) ? _interval.Hour(): 0) * MinutesPerHour + - ((_interval.Minute() != (uint8_t)(~0)) ? _interval.Minute():0)) * SecondsPerMinute + _interval.Second()) * MilliSecondsPerSecond; + uint64_t intervalTime = ((((_interval.Hours() != (uint8_t)(~0)) ? _interval.Hours(): 0) * MinutesPerHour + + ((_interval.Minutes() != (uint8_t)(~0)) ? _interval.Minutes():0)) * SecondsPerMinute + _interval.Seconds()) * MilliSecondsPerSecond; scheduledTime.Add(intervalTime); PluginHost::WorkerPool::Instance().Schedule(scheduledTime,Core::ProxyType(*this)); } @@ -595,7 +604,7 @@ class Launcher : public PluginHost::IPlugin { private: void Update(const ProcessObserver::Info& info); bool Execute(); - Core::Time FindAbsoluteTimeForSchedule(const Time absoluteTime, const Time interval); + Core::Time FindAbsoluteTimeForSchedule(const Time& absoluteTime, const Time& interval); private: PluginHost::IShell* _service; diff --git a/README.md b/README.md index 3851fe9..976d463 100644 --- a/README.md +++ b/README.md @@ -69,14 +69,14 @@ Plugin to "Launch" linux applications and scripts { "option": "-h"} ], "schedule": { - "absolute": false, + "mode": 0, "time": "06:04.10" } } ``` Note: -1. If field "absolute" is false or not set, it will treat the time as relative +1. If field "mode" is zero or not set, it will treat the time as relative 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. 3. If time format given is a. "XX", treat it as SS @@ -93,7 +93,7 @@ Note: { "option": "-h"} ], "schedule": { - "absolute": true, + "mode": 1, "time": "06:04.10" } } @@ -121,7 +121,7 @@ Note: { "option": "-h"} ], "schedule": { - "absolute": false, + "mode": 2, "time": "06:04.10", "interval": "00:40.10" } @@ -130,8 +130,9 @@ Note: Note: 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. -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. +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. 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) +3. If mode is 0(relative) or 1(absolute), the interval time will be taken only for the subsequent scheduling # How to launch multiple scripts/applcations From b3356a5a51cad59e2f2ffb378f45780093f27eff Mon Sep 17 00:00:00 2001 From: HaseenaSainul Date: Wed, 23 Jan 2019 00:37:03 +0530 Subject: [PATCH 3/3] Minor corrections as per code review comments --- Launcher.cpp | 22 ++++++++++++---------- README.md | 12 ++++++------ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Launcher.cpp b/Launcher.cpp index ac766b7..7585e8a 100644 --- a/Launcher.cpp +++ b/Launcher.cpp @@ -7,7 +7,7 @@ ENUM_CONVERSION_BEGIN(Plugin::Launcher::mode) { Plugin::Launcher::mode::RELATIVE, _TXT("relative") }, { Plugin::Launcher::mode::ABSOLUTE, _TXT("absolute") }, - { Plugin::Launcher::mode::ABSOLUTE_WITH_INTERVAL, _TXT("absolute_with_interval") }, + { Plugin::Launcher::mode::ABSOLUTE_WITH_INTERVAL, _TXT("interval") }, ENUM_CONVERSION_END(Plugin::Launcher::mode) ; @@ -219,21 +219,23 @@ Core::Time Launcher::FindAbsoluteTimeForSchedule(const Time& absoluteTime, const } } else { - if (slotTime >= startTime) { - uint32_t jump (absoluteTime.HasHours() ? HoursPerDay * MinutesPerHour * SecondsPerMinute : (absoluteTime.HasMinutes() ? MinutesPerHour * SecondsPerMinute : SecondsPerMinute)); - - // Go back the biggest chunk of the absoluteTime - slotTime.Sub(jump * 100); - } uint32_t intervalJump = ( (interval.HasHours() ? interval.Hours() * MinutesPerHour * SecondsPerMinute : 0) + (interval.HasMinutes() ? interval.Minutes() * SecondsPerMinute : 0) + interval.Seconds() ) * 100; ASSERT (intervalJump != 0); + if (slotTime >= startTime) { + Core::Time workTime (slotTime); - // Now increment with the intervall till we reach a valid point - while (slotTime < startTime) { - slotTime.Add(intervalJump); + while (workTime.Sub(intervalJump) > startTime) { + slotTime.Sub(intervalJump); + } + } + else { + // Now increment with the intervall till we reach a valid point + while (slotTime < startTime) { + slotTime.Add(intervalJump); + } } } diff --git a/README.md b/README.md index 976d463..c2bf10b 100644 --- a/README.md +++ b/README.md @@ -69,14 +69,14 @@ Plugin to "Launch" linux applications and scripts { "option": "-h"} ], "schedule": { - "mode": 0, + "mode": "relative", "time": "06:04.10" } } ``` Note: -1. If field "mode" is zero or not set, it will treat the time as relative +1. If field "mode" is empty or not set, it will treat the time as relative 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. 3. If time format given is a. "XX", treat it as SS @@ -93,7 +93,7 @@ Note: { "option": "-h"} ], "schedule": { - "mode": 1, + "mode": "absolute", "time": "06:04.10" } } @@ -121,7 +121,7 @@ Note: { "option": "-h"} ], "schedule": { - "mode": 2, + "mode": "interval", "time": "06:04.10", "interval": "00:40.10" } @@ -130,9 +130,9 @@ Note: Note: 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. -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. +2. If mode is interval (absolute with interval) and interval is set, it will identify next matching time and schedule application launch to that time. 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) -3. If mode is 0(relative) or 1(absolute), the interval time will be taken only for the subsequent scheduling +3. If mode is relative or absolute, the interval time will be taken only for the subsequent scheduling # How to launch multiple scripts/applcations