Skip to content

How to write your code

mtwebit edited this page Feb 3, 2019 · 6 revisions

Tasker will execute the long-running job in steps.
It's pretty simple but your code needs to be prepared for this.

Writing a function to be called by Tasker

Your function performs a long running job. There are two consequences:

  • Prepare to be interrupted (due to time/memory limits or events like ctrl+c) and continued later
  • Periodically report the progress to the user

Tasker provides help for solving both: a persistent storage ($taskData array) and a callback to save and report progress. Some runtime parameters (including a reference to the $task object) is also passed to your function.

The skeleton of a long running job may look like this

function my_long_running_function($page, &$taskData, $params) {
  // initialize task data if this is the first invocation
  if (!$taskData['records_processed']) {
    $taskData['max_records'] = ... estimate task size: count records, file size etc.
  }

  // check if we have anything left to do
  if ($taskData['records_processed'] == $taskData['max_records']) {
    $taskData['task_done'] = 1;
    $this->message('All records have been processed.');
    return true;
  }

  $tasker = wire('modules')->get('Tasker');
  $task = $params['task'];

  // array of processed entries (used to display their title to the user)
  $processed = array();
  // the serial of the entry we process
  $entrySerial = 0;
  // the next milestone when we save and report progress
  $taskData['milestone'] = $taskData['records_processed'] + 20;

  // process data records
  foreach ($records and $record) {  // while fgets() etc.
    // skip records that have been processed
    if ($entrySerial++ <= $taskData['records_processed']) continue;

    if (!process_record($record)) { // the actual record processor
      $this->error('Error processing the record.');
      return false; // the task will be stopped
      // you may also report a warning message and continue with the next record
    }

    $taskData['records_processed']++;
    $processed[] = $record->title;

    // save the progress if a milestone was reached
    if ($tasker->saveProgressAtMilestone($task, $taskData, $params)) {
      $this->message('Processing successful for '.implode(', ', $processed));
      $taskData['milestone'] = $entrySerial + 20;
      $processed = array();
    }

    // check whether the task is still allowed to execute
    if (!$tasker->allowedToExecute($task, $params)) {
      $taskData['task_done'] = 0;
      break; // the foreach loop
    }
  } // end of the loop

  // check if we have processed all records
  if ($taskData['records_processed'] == $taskData['max_records']) {
    $taskData['task_done'] = 1;
    $this->message('All records have been processed.');
  }

  return true;
}

When the function returns Tasker will calculate the task's progress and saves everything (including PW log messages) to the task's page.

$tasker->saveProgressAtMilestone()

This method checks whether a milestone has been reached and returns true if yes. At milestones Tasker also saves the task's progress including log messages so monitoring tools (other threads) will see the updated task data.

$tasker->allowedToExecute()

This returns false if

  • time or memory execution limits are close,
  • the task has been deactivated,
  • an external event happened and the task should be stopped.

The $taskData array

This is a persistent storage that is stored in the task's page. It is passed by reference to your function.
You may store any data that fits into a PHP array and can be saved using json_encode().
There are some special members used by Tasker:

  • 'module': name of the class that holds the 'method';
  • 'method': name of the function to be called
  • 'pageid': ID of the parent page.
  • 'records_processed': number of records processed by your function (set to 0 at start)
  • 'max_records': maximum number of records to be processed
  • 'task_done': is the task done or not
  • 'dep': tasks that should be finished before the actual task can be executed
  • 'next_task': next task to be activated when the task is finished (handled automatically by Tasker)
  • 'milestone': the record number where the next milestone will be reached

The $params array

Tasker provides runtime parameters for the task's function in an array:

  • 'timeout': the time() when the task should be stopped
  • 'invoker': Tasker scheduler (cron, lazyCron) or username who invoked the task
  • 'task': reference to the task Page object

Clone this wiki locally