mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-06-15 18:05:50 +00:00
321 lines
8.3 KiB
C
321 lines
8.3 KiB
C
#include <uwsgi.h>
|
|
|
|
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;
|
|
uc->pid = -1;
|
|
return uc;
|
|
}
|
|
|
|
|
|
void uwsgi_opt_add_cron(char *opt, char *value, void *foobar) {
|
|
uwsgi_cron_add(value);
|
|
}
|
|
|
|
|
|
void uwsgi_opt_add_unique_cron(char *opt, char *value, void *foobar) {
|
|
struct uwsgi_cron *uc = uwsgi_cron_add(value);
|
|
uc->unique = 1;
|
|
}
|
|
|
|
|
|
#ifdef UWSGI_SSL
|
|
void uwsgi_opt_add_legion_cron(char *opt, char *value, void *foobar) {
|
|
char *space = strchr(value, ' ');
|
|
if (!space) {
|
|
uwsgi_log("invalid %s syntax, must be prefixed with a legion name\n", opt);
|
|
exit(1);
|
|
}
|
|
char *legion = uwsgi_concat2n(value, space-value, "", 0);
|
|
struct uwsgi_cron *uc = uwsgi_cron_add(space+1);
|
|
uc->legion = legion;
|
|
}
|
|
|
|
|
|
void uwsgi_opt_add_unique_legion_cron(char *opt, char *value, void *foobar) {
|
|
char *space = strchr(value, ' ');
|
|
if (!space) {
|
|
uwsgi_log("invalid %s syntax, must be prefixed with a legion name\n", opt);
|
|
exit(1);
|
|
}
|
|
char *legion = uwsgi_concat2n(value, space-value, "", 0);
|
|
struct uwsgi_cron *uc = uwsgi_cron_add(space+1);
|
|
uc->legion = legion;
|
|
uc->unique = 1;
|
|
}
|
|
#endif
|
|
|
|
|
|
void uwsgi_opt_add_cron2(char *opt, char *value, void *foobar) {
|
|
|
|
char *c_minute = NULL;
|
|
char *c_hour = NULL;
|
|
char *c_day = NULL;
|
|
char *c_month = NULL;
|
|
char *c_week = NULL;
|
|
char *c_unique = NULL;
|
|
char *c_harakiri = NULL;
|
|
char *c_legion = NULL;
|
|
|
|
char *c_command = value;
|
|
|
|
char *space = strchr(value, ' ');
|
|
if (space) {
|
|
if (uwsgi_str_contains(value, space - value, '=')) {
|
|
// --cron2 key=val command
|
|
*space = 0;
|
|
c_command = space + 1;
|
|
}
|
|
|
|
// no point in parsing key=val list if there is none
|
|
if (uwsgi_kvlist_parse(value, strlen(value), ',', '=',
|
|
"minute", &c_minute,
|
|
"hour", &c_hour,
|
|
"day", &c_day,
|
|
"month", &c_month,
|
|
"week", &c_week,
|
|
"unique", &c_unique,
|
|
"harakiri", &c_harakiri,
|
|
"legion", &c_legion,
|
|
NULL)) {
|
|
uwsgi_log("unable to parse cron definition: %s\n", value);
|
|
exit(1);
|
|
}
|
|
}
|
|
else {
|
|
if (uwsgi_str_contains(value, strlen(value), '=')) {
|
|
// --cron2 key=val
|
|
uwsgi_log("unable to parse cron definition: %s\n", value);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
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));
|
|
|
|
uc->command = c_command;
|
|
if (!uc->command) {
|
|
uwsgi_log("[uwsgi-cron] invalid command in cron definition: %s\n", value);
|
|
exit(1);
|
|
}
|
|
|
|
// defaults
|
|
uc->minute = -1;
|
|
uc->hour = -1;
|
|
uc->day = -1;
|
|
uc->month = -1;
|
|
uc->week = -1;
|
|
|
|
uc->unique = 0;
|
|
uc->mercy = 0;
|
|
uc->harakiri = 0;
|
|
uc->pid = -1;
|
|
|
|
#ifdef UWSGI_SSL
|
|
uc->legion = c_legion;
|
|
#endif
|
|
|
|
if (c_minute)
|
|
uc->minute = atoi(c_minute);
|
|
|
|
if (c_hour)
|
|
uc->hour = atoi(c_hour);
|
|
|
|
if (c_day)
|
|
uc->day = atoi(c_day);
|
|
|
|
if (c_month)
|
|
uc->month = atoi(c_month);
|
|
|
|
if (c_week)
|
|
uc->week = atoi(c_week);
|
|
|
|
if (c_unique)
|
|
uc->unique = atoi(c_unique);
|
|
|
|
if (c_harakiri) {
|
|
if (atoi(c_harakiri)) {
|
|
// harakiri > 0
|
|
uc->mercy = atoi(c_harakiri);
|
|
}
|
|
else {
|
|
// harakiri == 0
|
|
uc->mercy = -1;
|
|
}
|
|
}
|
|
else if (uwsgi.cron_harakiri) {
|
|
uc->harakiri = uwsgi.cron_harakiri;
|
|
}
|
|
}
|
|
|
|
|
|
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))
|
|
goto next;
|
|
}
|
|
#endif
|
|
|
|
// skip unique crons that are still running
|
|
if (current_cron->unique && current_cron->pid >= 0)
|
|
goto next;
|
|
|
|
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 {
|
|
pid_t pid = uwsgi_run_command(current_cron->command, NULL, -1);
|
|
if (pid >= 0) {
|
|
current_cron->pid = pid;
|
|
current_cron->started_at = now;
|
|
uwsgi_log_verbose("[uwsgi-cron] running \"%s\" (pid %d)\n", current_cron->command, current_cron->pid);
|
|
if (current_cron->mercy) {
|
|
//uwsgi_cron->mercy can be negative to inform master that harakiri should be disabled for this cron
|
|
if (current_cron->mercy > 0)
|
|
current_cron->harakiri = now + current_cron->mercy;
|
|
}
|
|
else if (uwsgi.cron_harakiri)
|
|
current_cron->harakiri = now + uwsgi.cron_harakiri;
|
|
}
|
|
}
|
|
}
|
|
current_cron->last_job = now;
|
|
}
|
|
}
|
|
|
|
next:
|
|
current_cron = current_cron->next;
|
|
}
|
|
}
|
|
|