@@ -82,26 +82,34 @@ void scheduler::stop() {
8282 log_trace (__FILE__, __LINE__, " Thread pool contains: " + str::xtos (threads_.count ()));
8383}
8484
85- int scheduler::add_task (const std::string &tag, const boost::posix_time::time_duration duration, const double jitter_factor) {
85+ int scheduler::add_task (const std::string &tag, const boost::posix_time::time_duration duration, const double jitter_factor, const bool schedule_first_run ) {
8686 task item (tag, duration, jitter_factor);
8787 {
8888 boost::mutex::scoped_lock l (mutex_);
8989 item.id = ++schedule_id_;
9090 tasks_[item.id ] = item;
9191 }
92- reschedule (item, now ());
92+ if (schedule_first_run) reschedule (item, now ());
9393 return item.id ;
9494}
95- int scheduler::add_task (const std::string &tag, const cron_parser::schedule &schedule) {
95+ int scheduler::add_task (const std::string &tag, const cron_parser::schedule &schedule, const bool schedule_first_run ) {
9696 task item (tag, schedule);
9797 {
9898 boost::mutex::scoped_lock l (mutex_);
9999 item.id = ++schedule_id_;
100100 tasks_[item.id ] = item;
101101 }
102- reschedule (item, now ());
102+ if (schedule_first_run) reschedule (item, now ());
103103 return item.id ;
104104}
105+ void scheduler::run_now (const int id, const boost::posix_time::time_duration delay) {
106+ const op_task_object item = get_task (id);
107+ if (!item) {
108+ log_error (__FILE__, __LINE__, " Cannot run unknown task: " + str::xtos (id));
109+ return ;
110+ }
111+ reschedule_at (item->tag , id, now () + delay, true );
112+ }
105113void scheduler::remove_task (const int id) {
106114 boost::mutex::scoped_lock l (mutex_);
107115 const auto it = tasks_.find (id);
@@ -120,8 +128,14 @@ scheduler::op_task_object scheduler::get_task(const int id) {
120128}
121129
122130void scheduler::clear_tasks () {
123- boost::mutex::scoped_lock l (mutex_);
124- tasks_.clear ();
131+ {
132+ boost::mutex::scoped_lock l (mutex_);
133+ tasks_.clear ();
134+ }
135+ // Drop the pending instances as well: without a task behind them they would
136+ // only produce "Task not found" errors as they come due, and on a reload
137+ // they would race the freshly added tasks.
138+ if (!queue_.clear ()) log_error (__FILE__, __LINE__, " Failed to clear the schedule queue" );
125139}
126140
127141void scheduler::watch_dog (const int id) {
@@ -182,7 +196,7 @@ void scheduler::thread_proc(const int id) {
182196
183197 try {
184198 boost::posix_time::time_duration off = now () - instance->time ;
185- if (off.total_seconds () > error_threshold_) {
199+ if (!instance-> suppress_late_warning && off.total_seconds () > error_threshold_) {
186200 log_error (__FILE__, __LINE__,
187201 " Ran scheduled item " + instance->tag + " (" + str::xtos (instance->schedule_id ) + " ) " + str::xtos (off.total_seconds ()) +
188202 " seconds to late from thread " + str::xtos (id));
@@ -256,11 +270,12 @@ void scheduler::reschedule(const task &item, boost::posix_time::ptime now_time)
256270 reschedule_at (item.tag , item.id , item.get_next (now_time));
257271 }
258272}
259- void scheduler::reschedule_at (const std::string &tag, const int id, boost::posix_time::ptime new_time) {
273+ void scheduler::reschedule_at (const std::string &tag, const int id, boost::posix_time::ptime new_time, const bool suppress_late_warning ) {
260274 schedule_instance instance;
261275 instance.tag = tag;
262276 instance.schedule_id = id;
263277 instance.time = new_time;
278+ instance.suppress_late_warning = suppress_late_warning;
264279 if (!queue_.push (instance)) {
265280 log_error (__FILE__, __LINE__, " Failed to reschedule item" );
266281 }
0 commit comments