Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable/remove task #4

Open
asmyasnikov opened this issue Jan 29, 2018 · 5 comments
Open

Disable/remove task #4

asmyasnikov opened this issue Jan 29, 2018 · 5 comments

Comments

@asmyasnikov
Copy link

asmyasnikov commented Jan 29, 2018

Hello!
Tell me how to disable/remove task, created by interval/every method?
This need to me for stopping execution task without restart sheduller...
For example I may throw spatial exception from body of task, which cancelled schedulling this task in a future...

@klukaspl
Copy link

Hi,

I will be also interested in how to disable or remove particular task that is already set. How can I refer to each particular task in the scheduler?

BR,

Krzysztof

@Bosma
Copy link
Owner

Bosma commented Mar 2, 2018

Yes I agree this feature is required. I have some choices on how to implement it and would love any suggestions. I'll begin work on it some time soon.

@klukaspl
Copy link

Hi,
Maybe it could based on unique id of each task or applied name?
Then probably the time of execution, execution function and the name/uid is necessary to pass when adding to the pool. And to remove the task we could refer by its name to point it.

I am not sure if this is the simplest way - but maybe worth of consider.

In my application I need to define some schedules that could for example switchON the device and then switchOFF. For this I need for example use two separate tasks "at" type, or if it is recurring action two "cron" tasks. I was thinking to build some object as schedule for example "Schedule(ScheduleName, timeOn, timeOff)" and in the background launch two separate tasks .at(dateON, OnAction) and .at(dateOFF, OffAction). When they are run at once they will be deleted. But when I have recurrent schedule and I am trying to use .cron(dateON, OnAction) and .cron(dateOFF, OffAction) I have no reference to those created tasks and later on I could have problem when user will decide to delete those tasks.

@asmyasnikov
Copy link
Author

asmyasnikov commented Mar 14, 2018

Hi!
Disabling task by id is not safely. Because any code block may be called method of disabling task by random id without guarantee of disabling specific task.
I suggest throw exception from specific task who needed to disabling. And Scheduller was catch exception in manage_tasks() like this
try{ task->f(); }catch(SchedullerDisableException e){ end_of_tasks_to_run.insert(task); }
And task may be like this
std::atomic<bool> flag; s.in(1min, []() { if(flag) std::cout << "in one minute" << std::endl; else throw SchedullerDisableException(); });

@klukaspl
Copy link

klukaspl commented Mar 19, 2018

Hi,

Thanks, I agree that this could be a way. I am currently trying to test what you suggest. One question, I suppose that end_of_tasks_to_run is some kind of container? How to delete the task from the task to do list?
EDIT: end_of_tasks_to_run does not have insert member function.
EDIT: calling the exception on my side is just causing that the action is not executed on schedule period - it could be way of enabling/disabling task.
When catching the exception I am trying to call some my function delete_task to remove the task totally
from execution queue (from tasks).
It looks like that:
void delete_task(std::shared_ptr &t)
{
std::cout << "Here place delete action" << std::endl;

     for(auto it = tasks.begin(); it != tasks.end(); it++){
         if(it->second == t){
             std::cout << "The element found for time " << '\n';
             tasks.erase(it->first, it->second);
         }
     }
  }

but it seems it is never executed.
My manage_task looks as follow:

`
void manage_tasks()
{
std::lock_guardstd::mutex l(lock);
auto end_of_tasks_to_run = tasks.upper_bound(Clock::now());
std::shared_ptrBosma::Task &task = (*(tasks.begin())).second;

 try {

      // if there are any tasks to be run and removed
      if (end_of_tasks_to_run != tasks.begin()) {
        // keep track of tasks that will be re-added
        decltype(tasks) recurred_tasks;

        // for all tasks that have been triggered
        for (auto i = tasks.begin(); i != end_of_tasks_to_run; ++i) {
          task = (*i).second;

          if (task->interval) {
            // if it's an interval task, only add the task back after f() is completed
            threads.push([this, task](int) {
                task->f();
                // no risk of race-condition,
                // add_task() will wait for manage_tasks() to release lock
                add_task(task->get_new_time(), task);
            });
          } else {
            threads.push([task](int) {
                task->f();
            });
            // calculate time of next run and add the new task to the tasks to be recurred
            if (task->recur)
              recurred_tasks.emplace(task->get_new_time(), std::move(task));
          }
        }

        // remove the completed tasks
        tasks.erase(tasks.begin(), end_of_tasks_to_run);

        // re-add the tasks that are recurring
        for (auto &task : recurred_tasks)
          tasks.emplace(task.first, std::move(task.second));
      }
    }
    catch(SchedulerDisableException e)
    {
         std::cout << "here call the method to remove the particular task" << std::endl;
         delete_task(task);
    }

}
`
Do you have any idea how to force it to work?

BR,

Krzysztof.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants