36#include "cmdhandler.h"
39#include "clientpipe.h"
46static const char *module_str =
"time_leap_cmd";
53 " --time <time> aka -t \n"
62 "*WARNING* time leap is a debugging/testing tool, it should NEVER be used\n"
63 "in production! Without arguments the daemon inspects the first task in the\n"
64 "schedule and sets its internal time to the time of the task. This allows for\n"
65 "a quick replay of a test scenario. With the --time or -t switch the daemon\n"
66 "sets its time to the argument given as: \"YYYY-MM-DD-HH:MM:SS\"."
69 "time leap to this exact time\n"
70 "attach Perform 1 task and stay attached, use only when workerthreads=0\n\n"
75run(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
78 struct tm strtime_struct;
80 char buf[ODS_SE_MAXLINE];
81 time_t now = time_now();
82 const char *time = NULL;
88 int argc = 0, attach = 0;
89 int long_index = 0, opt = 0;
90 int processed_enforce;
91 task_type* task = NULL;
94 static struct option long_options[] = {
95 {
"time", required_argument, 0,
't'},
96 {
"attach", no_argument, 0,
'a'},
102 strncpy(buf, cmd,
sizeof(buf));
103 buf[
sizeof(buf)-1] =
'\0';
105 argc = ods_str_explode(buf,
NARGV, argv);
107 ods_log_error_and_printf(sockfd, module_str,
"too many arguments");
112 while ((opt = getopt_long(argc, (
char*
const*)argv,
"t:a", long_options, &long_index)) != -1) {
121 client_printf_err(sockfd,
"unknown arguments\n");
122 ods_log_error(
"[%s] unknown arguments for %s command",
129 if (strptime(time,
"%Y-%m-%d-%H:%M:%S", &tm)) {
131 time_leap = mktime(&tm);
132 client_printf(sockfd,
133 "Using %s parameter value as time to leap to\n", time);
135 client_printf_err(sockfd,
136 "Time leap: Error - could not convert '%s' to a time. "
137 "Format is YYYY-MM-DD-HH:MM:SS \n", time);
142 ods_log_assert(engine);
143 if (!engine->
taskq || !engine->
taskq->tasks) {
144 client_printf(sockfd,
"There are no tasks scheduled.\n");
148 schedule_info(engine->
taskq, &time_leap, NULL, &taskcount);
150 strftime(strtime,
sizeof(strtime),
"%c", localtime_r(&now, &strtime_struct));
151 client_printf(sockfd,
152 "There are %i tasks scheduled.\nIt is now %s (%ld seconds since epoch)\n",
153 taskcount, strtime, (
long)now);
155 if (!time) schedule_info(engine->
taskq, &time_leap, NULL, NULL);
156 if (time_leap == -1) {
157 client_printf(sockfd,
"No tasks in queue. Not able to leap.\n");
162 set_time_now(time_leap);
163 strftime(strtime,
sizeof(strtime),
"%c", localtime_r(&time_leap, &strtime_struct));
164 client_printf(sockfd,
"Leaping to time %s (%ld seconds since epoch)\n",
165 (strtime[0]?strtime:
"(null)"), (
long)time_leap);
166 ods_log_info(
"Time leap: Leaping to time %s\n", strtime);
169 client_printf(sockfd,
"Waking up workers\n");
175 client_printf_err(sockfd,
"Failed to open DB connection.\n");
176 client_exit(sockfd, 1);
180 processed_enforce = 0;
184 schedule_info(engine->
taskq, &time_leap, NULL, NULL);
185 if (processed_enforce && time_leap > time_now())
break;
187 if (time_leap == -1) {
188 client_printf(sockfd,
"No tasks in queue. Not able to leap.\n");
192 set_time_now(time_leap);
193 strftime(strtime,
sizeof(strtime),
"%c", localtime_r(&time_leap, &strtime_struct));
194 client_printf(sockfd,
"Leaping to time %s (%ld seconds since epoch)\n",
195 (strtime[0]?strtime:
"(null)"), (
long)time_leap);
196 ods_log_info(
"Time leap: Leaping to time %s\n", strtime);
197 if (!(task = schedule_pop_first_task(engine->
taskq)))
199 if (schedule_task_istype(task, TASK_TYPE_ENFORCE))
200 processed_enforce = 1;
201 task_perform(engine->
taskq, task, dbconn);
202 ods_log_debug(
"[timeleap] finished working");
210 "time leap", &usage, &help, NULL, &run
void db_connection_free(db_connection_t *connection)
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
void engine_wakeup_workers(engine_type *engine)
db_connection_t * get_database_connection(engine_type *engine)
struct cmd_func_block time_leap_funcblock