From e68fefeac780e6c87c6ca4722027288356eb0cc8 Mon Sep 17 00:00:00 2001 From: "Jose M. Guisado" Date: Thu, 11 Mar 2021 09:40:04 +0100 Subject: #997 Set stale check flag when processing schedule/create If you schedule a command in the past, the scheduler executes such command immediately. When expanding a schedule that result in commands that run weekly, commands in the past are also executed, which is not expected. Fix this by using the check_stale flag (formerly on_start) so commands in the past that result from expansions are skipped. --- src/rest.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/schedule.c | 18 +++++++-------- src/schedule.h | 2 +- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/rest.c b/src/rest.c index 57a97a5..8826d66 100644 --- a/src/rest.c +++ b/src/rest.c @@ -3234,7 +3234,7 @@ int og_dbi_schedule_get(void) time.hours = dbi_result_get_uint(result, "horas"); time.am_pm = dbi_result_get_uint(result, "ampm"); time.minutes = dbi_result_get_uint(result, "minutos"); - time.on_start = true; + time.check_stale = true; og_schedule_create(schedule_id, task_id, OG_SCHEDULE_TASK, &time); @@ -3485,8 +3485,59 @@ static int og_task_schedule_create(struct og_msg_params *params) return 0; } +static uint32_t og_tm_years_mask(struct tm *tm) +{ + int i, j = 0; + + for (i = 2010; i < 2026; i++, j++) { + if (tm->tm_year + 1900 == i) + break; + } + + return (1 << j); +} + +static uint32_t og_tm_months_mask(struct tm *tm) +{ + return 1 << tm->tm_mon; +} + +static uint32_t og_tm_hours_mask(struct tm *tm) +{ + return 1 << (tm->tm_hour - 12); +} + +static uint32_t og_tm_ampm(struct tm *tm) +{ + return tm->tm_hour < 12 ? 0 : 1; +} + +static uint32_t og_tm_days_mask(struct tm *tm) +{ + return 1 << (tm->tm_mday - 1); +} + +static void og_schedule_time_now(struct og_schedule_time *ogtime) +{ + struct tm *tm; + time_t now; + + now = time(NULL); + tm = localtime(&now); + + ogtime->years = og_tm_years_mask(tm); + ogtime->months = og_tm_months_mask(tm); + ogtime->weeks = 0; + ogtime->week_days = 0; + ogtime->days = og_tm_days_mask(tm); + ogtime->hours = og_tm_hours_mask(tm); + ogtime->am_pm = og_tm_ampm(tm); + ogtime->minutes = tm->tm_min; +} + static int og_cmd_schedule_create(json_t *element, struct og_msg_params *params) { + bool when = false; const char *key; json_t *value; int err; @@ -3503,6 +3554,7 @@ static int og_cmd_schedule_create(json_t *element, struct og_msg_params *params) params->flags |= OG_REST_PARAM_NAME; } else if (!strcmp(key, "when")) { err = og_json_parse_time_params(value, params); + when = true; } else if (!strcmp(key, "type")) { err = og_json_parse_string(value, ¶ms->type); params->flags |= OG_REST_PARAM_TYPE; @@ -3512,6 +3564,21 @@ static int og_cmd_schedule_create(json_t *element, struct og_msg_params *params) break; } + if (!when) { + params->time.check_stale = false; + og_schedule_time_now(¶ms->time); + params->flags |= OG_REST_PARAM_TIME_YEARS | + OG_REST_PARAM_TIME_MONTHS | + OG_REST_PARAM_TIME_WEEKS | + OG_REST_PARAM_TIME_WEEK_DAYS | + OG_REST_PARAM_TIME_DAYS | + OG_REST_PARAM_TIME_HOURS | + OG_REST_PARAM_TIME_AM_PM | + OG_REST_PARAM_TIME_MINUTES; + } else { + params->time.check_stale = true; + } + if (!og_msg_params_validate(params, OG_REST_PARAM_TASK | OG_REST_PARAM_NAME | OG_REST_PARAM_TIME_YEARS | diff --git a/src/schedule.c b/src/schedule.c index 6dc54e0..9fb272c 100644 --- a/src/schedule.c +++ b/src/schedule.c @@ -212,7 +212,7 @@ static void og_schedule_create_weekdays(int month, int year, int *hours, int minutes, int week_days, uint32_t task_id, uint32_t schedule_id, enum og_schedule_type type, - bool on_start) + bool check_stale) { struct og_schedule *schedule; int month_days[5]; @@ -244,7 +244,7 @@ static void og_schedule_create_weekdays(int month, int year, tm.tm_min = minutes; seconds = mktime(&tm); - if (on_start && og_schedule_stale(seconds)) + if (check_stale && og_schedule_stale(seconds)) continue; schedule = (struct og_schedule *) @@ -265,7 +265,7 @@ static void og_schedule_create_weekdays(int month, int year, static void og_schedule_create_weeks(int month, int year, int *hours, int minutes, int weeks, uint32_t task_id, uint32_t schedule_id, - enum og_schedule_type type, bool on_start) + enum og_schedule_type type, bool check_stale) { struct og_schedule *schedule; int month_days[7]; @@ -300,7 +300,7 @@ static void og_schedule_create_weeks(int month, int year, tm.tm_min = minutes; seconds = mktime(&tm); - if (on_start && og_schedule_stale(seconds)) + if (check_stale && og_schedule_stale(seconds)) continue; schedule = (struct og_schedule *) @@ -321,7 +321,7 @@ static void og_schedule_create_weeks(int month, int year, static void og_schedule_create_days(int month, int year, int *hours, int minutes, int *days, uint32_t task_id, uint32_t schedule_id, - enum og_schedule_type type, bool on_start) + enum og_schedule_type type, bool check_stale) { struct og_schedule *schedule; time_t seconds; @@ -339,7 +339,7 @@ static void og_schedule_create_days(int month, int year, tm.tm_min = minutes; seconds = mktime(&tm); - if (on_start && og_schedule_stale(seconds)) + if (check_stale && og_schedule_stale(seconds)) continue; schedule = (struct og_schedule *) @@ -385,7 +385,7 @@ void og_schedule_create(unsigned int schedule_id, unsigned int task_id, task_id, schedule_id, type, - time->on_start); + time->check_stale); if (time->weeks) og_schedule_create_weeks(month, year, @@ -393,7 +393,7 @@ void og_schedule_create(unsigned int schedule_id, unsigned int task_id, time->weeks, task_id, schedule_id, - type, time->on_start); + type, time->check_stale); if (time->days) og_schedule_create_days(month, year, @@ -401,7 +401,7 @@ void og_schedule_create(unsigned int schedule_id, unsigned int task_id, days, task_id, schedule_id, - type, time->on_start); + type, time->check_stale); } } diff --git a/src/schedule.h b/src/schedule.h index 14b8998..12c394c 100644 --- a/src/schedule.h +++ b/src/schedule.h @@ -16,7 +16,7 @@ struct og_schedule_time { uint32_t hours; uint32_t am_pm; uint32_t minutes; - bool on_start; + bool check_stale; }; enum og_schedule_type { -- cgit v1.2.3-18-g5258