From 96b92c98ff6879278aa670fc4f5acd9582a24bb2 Mon Sep 17 00:00:00 2001 From: Unbit Date: Sat, 13 Apr 2013 09:22:22 +0200 Subject: [PATCH] refactored cron to allows better plugins integration --- core/cron.c | 182 ++++++++++++++++++++++++++++++++++++++++++++ core/master_utils.c | 90 ---------------------- core/signal.c | 80 ------------------- uwsgi.h | 2 + uwsgiconfig.py | 2 +- 5 files changed, 185 insertions(+), 171 deletions(-) create mode 100644 core/cron.c diff --git a/core/cron.c b/core/cron.c new file mode 100644 index 00000000..f58528dc --- /dev/null +++ b/core/cron.c @@ -0,0 +1,182 @@ +#include + +extern struct uwsgi_server uwsgi; + +struct uwsgi_cron *uwsgi_cron_add(char *crontab) { + int i; + struct uwsgi_cron *old_uc, *uc = uwsgi.crons; + if (!uc) { + uc = uwsgi_malloc(sizeof(struct uwsgi_cron)); + uwsgi.crons = uc; + } + else { + old_uc = uc; + while (uc->next) { + uc = uc->next; + old_uc = uc; + } + + old_uc->next = uwsgi_malloc(sizeof(struct uwsgi_cron)); + uc = old_uc->next; + } + + memset(uc, 0, sizeof(struct uwsgi_cron)); + + if (sscanf(crontab, "%d %d %d %d %d %n", &uc->minute, &uc->hour, &uc->day, &uc->month, &uc->week, &i) != 5) { + uwsgi_log("invalid cron syntax\n"); + exit(1); + } + uc->command = crontab + i; + return uc; +} + +void uwsgi_opt_add_cron(char *opt, char *value, void *foobar) { + uwsgi_cron_add(value); +} + +#ifdef UWSGI_SSL +void uwsgi_opt_add_legion_cron(char *opt, char *value, void *foobar) { + char *space = strchr(value, ' '); + if (!space) { + uwsgi_log("invalid legion-cron syntax, must be prefixed with a legion name\n"); + exit(1); + } + char *legion = uwsgi_concat2n(value, space-value, "", 0); + uwsgi_opt_add_cron(opt, space+1, foobar); + // now get the last added uwsgi_cron structure + struct uwsgi_cron *uc = uwsgi.crons; + while(uc) { + if (!uc->next) { + uc->legion = legion; + return; + } + } + + uwsgi_log("error initializing legion-cron\n"); + exit(1); +} +#endif + + +int uwsgi_signal_add_cron(uint8_t sig, int minute, int hour, int day, int month, int week) { + + if (!uwsgi.master_process) + return -1; + + uwsgi_lock(uwsgi.cron_table_lock); + + if (ushared->cron_cnt < MAX_CRONS) { + + ushared->cron[ushared->cron_cnt].sig = sig; + ushared->cron[ushared->cron_cnt].minute = minute; + ushared->cron[ushared->cron_cnt].hour = hour; + ushared->cron[ushared->cron_cnt].day = day; + ushared->cron[ushared->cron_cnt].month = month; + ushared->cron[ushared->cron_cnt].week = week; + ushared->cron_cnt++; + } + else { + uwsgi_log("you can register max %d cron !!!\n", MAX_CRONS); + uwsgi_unlock(uwsgi.cron_table_lock); + return -1; + } + + uwsgi_unlock(uwsgi.cron_table_lock); + + return 0; +} + +void uwsgi_manage_signal_cron(time_t now) { + + struct tm *uwsgi_cron_delta; + int i; + + uwsgi_cron_delta = localtime(&now); + + if (uwsgi_cron_delta) { + + // fix month + uwsgi_cron_delta->tm_mon++; + + uwsgi_lock(uwsgi.cron_table_lock); + for (i = 0; i < ushared->cron_cnt; i++) { + + struct uwsgi_cron *ucron = &ushared->cron[i]; + + int run_task = uwsgi_cron_task_needs_execution(uwsgi_cron_delta, ucron->minute, ucron->hour, ucron->day, ucron->month, ucron->week); + + if (run_task == 1) { + // date match, signal it ? + if (now - ucron->last_job >= 60) { + uwsgi_route_signal(ucron->sig); + ucron->last_job = now; + } + } + + } + uwsgi_unlock(uwsgi.cron_table_lock); + } + else { + uwsgi_error("localtime()"); + } + +} + +void uwsgi_manage_command_cron(time_t now) { + + struct tm *uwsgi_cron_delta; + + struct uwsgi_cron *current_cron = uwsgi.crons; + + uwsgi_cron_delta = localtime(&now); + + + if (!uwsgi_cron_delta) { + uwsgi_error("uwsgi_manage_command_cron()/localtime()"); + return; + } + + // fix month + uwsgi_cron_delta->tm_mon++; + + while (current_cron) { + +#ifdef UWSGI_SSL + // check for legion cron + if (current_cron->legion) { + if (!uwsgi_legion_i_am_the_lord(current_cron->legion)) { + current_cron = current_cron->next; + continue; + } + } +#endif + + int run_task = uwsgi_cron_task_needs_execution(uwsgi_cron_delta, current_cron->minute, current_cron->hour, current_cron->day, current_cron->month, current_cron->week); + + if (run_task == 1) { + + // date match, run command ? + if (now - current_cron->last_job >= 60) { + //call command + if (current_cron->command) { + if (current_cron->func) { + current_cron->func(current_cron, now); + } + else { + if (uwsgi_run_command(current_cron->command, NULL, -1) >= 0) { + uwsgi_log_verbose("[uwsgi-cron] running %s\n", current_cron->command); + } + } + } + current_cron->last_job = now; + } + } + + + + current_cron = current_cron->next; + } + + +} + diff --git a/core/master_utils.c b/core/master_utils.c index 302f9c58..8b032502 100644 --- a/core/master_utils.c +++ b/core/master_utils.c @@ -630,96 +630,6 @@ int uwsgi_respawn_worker(int wid) { return 0; } - -void uwsgi_manage_signal_cron(time_t now) { - - struct tm *uwsgi_cron_delta; - int i; - - uwsgi_cron_delta = localtime(&now); - - if (uwsgi_cron_delta) { - - // fix month - uwsgi_cron_delta->tm_mon++; - - uwsgi_lock(uwsgi.cron_table_lock); - for (i = 0; i < ushared->cron_cnt; i++) { - - struct uwsgi_cron *ucron = &ushared->cron[i]; - - int run_task = uwsgi_cron_task_needs_execution(uwsgi_cron_delta, ucron->minute, ucron->hour, ucron->day, ucron->month, ucron->week); - - if (run_task == 1) { - // date match, signal it ? - if (now - ucron->last_job >= 60) { - uwsgi_route_signal(ucron->sig); - ucron->last_job = now; - } - } - - } - uwsgi_unlock(uwsgi.cron_table_lock); - } - else { - uwsgi_error("localtime()"); - } - -} - -void uwsgi_manage_command_cron(time_t now) { - - struct tm *uwsgi_cron_delta; - - struct uwsgi_cron *current_cron = uwsgi.crons; - - uwsgi_cron_delta = localtime(&now); - - - if (!uwsgi_cron_delta) { - uwsgi_error("uwsgi_manage_command_cron()/localtime()"); - return; - } - - // fix month - uwsgi_cron_delta->tm_mon++; - - while (current_cron) { - -#ifdef UWSGI_SSL - // check for legion cron - if (current_cron->legion) { - if (!uwsgi_legion_i_am_the_lord(current_cron->legion)) { - current_cron = current_cron->next; - continue; - } - } -#endif - - int run_task = uwsgi_cron_task_needs_execution(uwsgi_cron_delta, current_cron->minute, current_cron->hour, current_cron->day, current_cron->month, current_cron->week); - - if (run_task == 1) { - - // date match, run command ? - if (now - current_cron->last_job >= 60) { - //call command - if (current_cron->command) { - if (uwsgi_run_command(current_cron->command, NULL, -1) >= 0) { - uwsgi_log_verbose("[uwsgi-cron] running %s\n", current_cron->command); - } - } - current_cron->last_job = now; - } - } - - - - current_cron = current_cron->next; - } - - -} - struct uwsgi_stats *uwsgi_master_generate_stats() { int i; diff --git a/core/signal.c b/core/signal.c index a366314f..a65892a0 100644 --- a/core/signal.c +++ b/core/signal.c @@ -203,86 +203,6 @@ int uwsgi_add_timer(uint8_t sig, int secs) { } -void uwsgi_opt_add_cron(char *opt, char *value, void *foobar) { - - int i; - - struct uwsgi_cron *old_uc, *uc = uwsgi.crons; - if (!uc) { - uc = uwsgi_malloc(sizeof(struct uwsgi_cron)); - uwsgi.crons = uc; - } - else { - old_uc = uc; - while (uc->next) { - uc = uc->next; - old_uc = uc; - } - - old_uc->next = uwsgi_malloc(sizeof(struct uwsgi_cron)); - uc = old_uc->next; - } - - memset(uc, 0, sizeof(struct uwsgi_cron)); - - if (sscanf(value, "%d %d %d %d %d %n", &uc->minute, &uc->hour, &uc->day, &uc->month, &uc->week, &i) != 5) { - uwsgi_log("invalid cron syntax\n"); - exit(1); - } - uc->command = value + i; -} - -#ifdef UWSGI_SSL -void uwsgi_opt_add_legion_cron(char *opt, char *value, void *foobar) { - char *space = strchr(value, ' '); - if (!space) { - uwsgi_log("invalid legion-cron syntax, must be prefixed with a legion name\n"); - exit(1); - } - char *legion = uwsgi_concat2n(value, space-value, "", 0); - uwsgi_opt_add_cron(opt, space+1, foobar); - // now get the last added uwsgi_cron structure - struct uwsgi_cron *uc = uwsgi.crons; - while(uc) { - if (!uc->next) { - uc->legion = legion; - return; - } - } - - uwsgi_log("error initializing legion-cron\n"); - exit(1); -} -#endif - -int uwsgi_signal_add_cron(uint8_t sig, int minute, int hour, int day, int month, int week) { - - if (!uwsgi.master_process) - return -1; - - uwsgi_lock(uwsgi.cron_table_lock); - - if (ushared->cron_cnt < MAX_CRONS) { - - ushared->cron[ushared->cron_cnt].sig = sig; - ushared->cron[ushared->cron_cnt].minute = minute; - ushared->cron[ushared->cron_cnt].hour = hour; - ushared->cron[ushared->cron_cnt].day = day; - ushared->cron[ushared->cron_cnt].month = month; - ushared->cron[ushared->cron_cnt].week = week; - ushared->cron_cnt++; - } - else { - uwsgi_log("you can register max %d cron !!!\n", MAX_CRONS); - uwsgi_unlock(uwsgi.cron_table_lock); - return -1; - } - - uwsgi_unlock(uwsgi.cron_table_lock); - - return 0; -} - int uwsgi_signal_add_rb_timer(uint8_t sig, int secs, int iterations) { if (!uwsgi.master_process) diff --git a/uwsgi.h b/uwsgi.h index 1f6531a7..c866eb29 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2321,6 +2321,7 @@ struct uwsgi_cron { #ifdef UWSGI_SSL char *legion; #endif + void (*func)(struct uwsgi_cron *, time_t); struct uwsgi_cron *next; }; @@ -3908,6 +3909,7 @@ char *uwsgi_get_mime_type(char *, int, size_t *); void config_magic_table_fill(char *, char *[]); int uwsgi_blob_to_response(struct wsgi_request *, char *, size_t); +struct uwsgi_cron *uwsgi_cron_add(char *); void uwsgi_check_emperor(void); #ifdef UWSGI_AS_SHARED_LIBRARY diff --git a/uwsgiconfig.py b/uwsgiconfig.py index f9f603b0..b3bc9d3b 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -456,7 +456,7 @@ class uConf(object): self.gcc_list = ['core/utils', 'core/protocol', 'core/socket', 'core/logging', 'core/master', 'core/master_utils', 'core/emperor', 'core/notify', 'core/mule', 'core/subscription', 'core/stats', 'core/sendfile', 'core/async', 'core/master_checks', 'core/offload', 'core/io', 'core/static', 'core/websockets', 'core/spooler', 'core/snmp', 'core/exceptions', 'core/config', - 'core/setup_utils', 'core/clock', 'core/init', 'core/buffer', 'core/reader', 'core/writer', 'core/alarm', + 'core/setup_utils', 'core/clock', 'core/init', 'core/buffer', 'core/reader', 'core/writer', 'core/alarm', 'core/cron', 'core/plugins', 'core/lock', 'core/cache', 'core/daemons', 'core/errors', 'core/hash', 'core/master_events', 'core/queue', 'core/event', 'core/signal', 'core/strings', 'core/progress', 'core/timebomb', 'core/ini', 'core/rpc', 'core/gateway', 'core/loop', 'core/cookie', 'core/querystring', 'core/rb_timers', 'core/uwsgi']