Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can the state (active or not) of a scheduled task be queried?

What is the preferred way to check whether a scheduled task is active or not?

I'll outline my solution below, but I am not sure this is indeed the best way to do it.


A scheduled task is created like this:

In[1]:= myTask=CreateScheduledTask[Print["task 1"], 30]

Out[1]= ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,False]

We can check for the existing tasks like this:

In[2]:= ScheduledTasks[]
Out[2]= {ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,False]}

The last entry in the ScheduledTaskObject (True or False) appears to indicate whether the task is started or not.

Now let's start the task, and compare the contents of the variable myTask with the list returned by ScheduledTasks[].

In[3]:= StartScheduledTask[myTask]
Out[3]= ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,False]

In[4]:= {ScheduledTasks[],myTask}
Out[4]= {{ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,True]},
          ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,False]}

Note that they differ. The variable shows False while ScheduledTasks[] shows false. This demonstrates that the variable does not actually hold the task object. By modifying the variable myTask directly we can't modify the task. The real state of the task is returned by ScheduledTasks[].

It looks reasonable to assume though that the first entry in the ScheduledTaskObject expression is a unique number corresponding to the task. So any manual operation performed on the task could perhaps use this number as a "handle", and we could check the state of task with identifier 1 like this:

Cases[ScheduledTasks[], ScheduledTaskObject[1,__,state_] :> state]

I am not sure at all though that this approach (using the identifier from the ScheduledTaskObject) is correct. I have noticed situations when there were already some tasks in a fresh kernel (probably due to the front end --- I had several notebook open, some with dynamic elements, and I've been experimenting with tasks), and sometimes ScheduledTasks[] returns several tasks with the same identifier (usually 0).

In summary:

  1. Is it a reliable way to handle tasks by their identifier (the first number from their ScheduledTaskObject)?

  2. What is the correct way to query the state of a scheduled task, given the expression we get from CreateScheduledTask when we first create it?

EDIT: If it's possible, it would also be nice to have a Dynamic cell showing the state of a scheduled task, without using too much CPU. Does anyone have any ideas about how to do this?

like image 725
Szabolcs Avatar asked Oct 29 '11 13:10

Szabolcs


1 Answers

The documentation for ScheduledTaskObject indeed uses id for the first argument and I think it is indeed unique. I have not been able to reproduce multiple ScheduledTaskObjects with the same id as you claim (nor ones with 0), so if you could provide a minimal example, it would be nice.

In any case (assuming more than one task has the same id), you can narrow down your match by also checking for the exact definition of the task. Here's a simple modification of yours.

 Clear@pollState
 pollState[task_ScheduledTaskObject] := 
 Module[{id = Level[task, 1][[1]], expr = Level[task, 1][[2]]},
  out = Cases[ScheduledTasks[], 
    ScheduledTaskObject[Evaluate@id, Evaluate@expr, __, state_] :> 
     state];
  Return[If[out === {}, "Task not found", First@out]]]

You can create a Dynamic output of the state of your task and set the update interval to something like 1 second (or more), so that it doesn't constantly poll for the state, hence slowing you down.

Dynamic[Refresh[pollState[myTask], UpdateInterval -> 1]]
like image 189
abcd Avatar answered Oct 12 '22 08:10

abcd