36#include "cmdhandler.h"
39#include "clientpipe.h"
41#include "longgetopt.h"
47static const char *module_str =
"time_leap_cmd";
54 " --time <time> aka -t \n"
63 "*WARNING* time leap is a debugging/testing tool, it should NEVER be used\n"
64 "in production! Without arguments the daemon inspects the first task in the\n"
65 "schedule and sets its internal time to the time of the task. This allows for\n"
66 "a quick replay of a test scenario. With the --time or -t switch the daemon\n"
67 "sets its time to the argument given as: \"YYYY-MM-DD-HH:MM:SS\"."
70 "time leap to this exact time\n"
71 "attach Perform 1 task and stay attached, use only when workerthreads=0\n\n"
76run(cmdhandler_ctx_type* context,
int argc,
char* argv[])
78 int sockfd = context->sockfd;
79 struct longgetopt optctx;
81 struct tm strtime_struct;
83 time_t now = time_now();
84 const char *time = NULL;
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'},
100 for (opt = longgetopt(argc, argv,
"t:a", long_options, &long_index, &optctx); opt != -1;
101 opt = longgetopt(argc, argv, NULL, long_options, &long_index, &optctx)) {
104 time = optctx.optarg;
110 client_printf_err(sockfd,
"unknown arguments\n");
111 ods_log_error(
"[%s] unknown arguments for time leap command", module_str);
117 if (strptime(time,
"%Y-%m-%d-%H:%M:%S", &tm)) {
119 time_leap = mktime(&tm);
120 client_printf(sockfd,
121 "Using %s parameter value as time to leap to\n", time);
123 client_printf_err(sockfd,
124 "Time leap: Error - could not convert '%s' to a time. "
125 "Format is YYYY-MM-DD-HH:MM:SS \n", time);
130 ods_log_assert(engine);
131 if (!engine->
taskq || !engine->
taskq->tasks) {
132 client_printf(sockfd,
"There are no tasks scheduled.\n");
136 schedule_info(engine->
taskq, &time_leap, NULL, &taskcount);
138 strftime(strtime,
sizeof(strtime),
"%c", localtime_r(&now, &strtime_struct));
139 client_printf(sockfd,
140 "There are %i tasks scheduled.\nIt is now %s (%ld seconds since epoch)\n",
141 taskcount, strtime, (
long)now);
143 if (!time) schedule_info(engine->
taskq, &time_leap, NULL, NULL);
144 if (time_leap == -1) {
145 client_printf(sockfd,
"No tasks in queue. Not able to leap.\n");
150 set_time_now(time_leap);
151 strftime(strtime,
sizeof(strtime),
"%c", localtime_r(&time_leap, &strtime_struct));
152 client_printf(sockfd,
"Leaping to time %s (%ld seconds since epoch)\n",
153 (strtime[0]?strtime:
"(null)"), (
long)time_leap);
154 ods_log_info(
"Time leap: Leaping to time %s\n", strtime);
157 client_printf(sockfd,
"Waking up workers\n");
163 client_printf_err(sockfd,
"Failed to open DB connection.\n");
164 client_exit(sockfd, 1);
168 processed_enforce = 0;
172 schedule_info(engine->
taskq, &time_leap, NULL, NULL);
173 if (processed_enforce && time_leap > time_now())
break;
175 if (time_leap == -1) {
176 client_printf(sockfd,
"No tasks in queue. Not able to leap.\n");
180 set_time_now(time_leap);
181 strftime(strtime,
sizeof(strtime),
"%c", localtime_r(&time_leap, &strtime_struct));
182 client_printf(sockfd,
"Leaping to time %s (%ld seconds since epoch)\n",
183 (strtime[0]?strtime:
"(null)"), (
long)time_leap);
184 ods_log_info(
"Time leap: Leaping to time %s\n", strtime);
185 if (!(task = schedule_pop_first_task(engine->
taskq)))
187 if (schedule_task_istype(task, TASK_TYPE_ENFORCE))
188 processed_enforce = 1;
189 task_perform(engine->
taskq, task, dbconn);
190 ods_log_debug(
"[timeleap] finished working");
198 "time leap", &usage, &help, NULL, NULL, &run, NULL
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