1. Home
  2. Docs
  3. Application Framework
  4. Classes & Patterns
  5. Tasks

Tasks

MWP\Framework\Task

When you need to process data sets which vary in size and runtime, its best to process the data in small iterations over a period of time to prevent unexpected explosions. Setup a task runner to process your data in the background in a way that is scalable.

Task::queueTask( $config, $data )

@Queue A Task

use MWP\Framework\Task;

$config = array
(
    // Action Hook
    // (required) the action which will be fired when this task is ran
    // i.e. register your callback using @MWP\WordPress\Action( for="my_task_action" )
    'action' => 'happy_hour',

    // Identification Tag
    // (optional) a tag which you can use to look up or delete this task later
    'tag' => 'identifier_tag',

    // Task Priority
    // (optional) a higher priority means it will be ran before lower priority tasks
    // defaults to 5 if not specified
    'priority' => 5,

    // Start Time
    // (optional) a timestamp that indicates a time that this task should wait to 
    // start next. It may not start exactly at this time, but it will not start any
    // earlier.
    'next_start' => time(),
);

// Data to be passed into your callback hook when the task is ran
$data = array( 'bottles_of_beer_on_wall' => 99 );

// Setup the task runner
Task::queueTask( $config, $data );

/**
 * Count tasks from queue based on action and or tag
 *
 * @param    string        $action            Count all tasks with specific action|NULL to ignore
 * @param    string        $tag            Count all tasks with specific tag|NULL to ignore
 * @return    void
 */
$total = Task::countTasks( 'happy_hour', 'identifier_tag' );

/**
 * Delete tasks from queue based on action and or tag
 *
 * @param    string        $action            Delete all tasks with specific action
 * @param    string        $tag            Delete all tasks with specific tag
 * @return    void
 */
Task::deleteTasks( 'happy_hour', 'unwanted_task_id' );

@Task Action Callbacks

When its time to process your task, the action you specified in your task configuration is invoked with the $task object being provided as the only parameter.

The following actions are triggered to run your task:

your_task_action_setup Called once and allows you to setup any resources for your task.
your_task_action Called repeatedly until your task either completes, or max run time is reached. your_task_action_shutdown Called once when the runner stops running your task, complete or not.

Setting data on your task allows it to persist between iterations and also between task runs.

/**
 * Set Task Data
 *
 * @param   string          $key            The data key to set
 * @param   mixed           $value          The value to set
 * @return  void
 */
public function setData( $key, $value )

/**
 * Get Task Data
 *
 * @param   string          $key            The data key to set
 * @return  mixed
 */
public function getData( $key )

Setting a task status will provide valuable feedback on the task administration screen as to the current state of your task.

/**
 * Set the task status
 *
 * @param   string              $status             The task status to display in the admin
 */
public function setStatus( $status )

When the task is completed, call the $task->complete() method.

/**
 * Complete the task
 *
 * @return  void
 */
public function complete()

When the task is aborted, it is left in the queue, but it’s failover is set so that it will not continue to be ran. This way you can provide a useful message to the end user to let them know why the task is not running and how they can rectify the situation. The end user will have the option to unlock the aborted task and let it run again once they’ve corrected the situation that caused your task to abort.

/**
 * Abort the task
 *
 * @return  void
 */
public function abort()

@Example Code

class MyClass
{

    /** 
     * Task bootstrap function (only called once per task session)
     * 
     * @MWP\WordPress\Action( for="happy_hour_setup" )
     */
    public function myTaskRunnerBootstrap( $task )
    {
           // a guy walks into a pub...
    }

    /** 
     * @MWP\WordPress\Action( for="happy_hour" )
     */
    public function myTaskRunner( $task )
    {
        $beer_left = $task->getData( 'bottles_of_beer_on_wall' );

        // if we have no more
        if ( $beer_left <= 0 ) {
            return $task->complete();
        }

        // drink a bottle of beer
        $bottles = $this->takeOneDownAndPassItAround( $beer_left );

        $task->setData( 'bottles_of_beer_on_wall', $bottles );

        // Set a status message for display on the admin
        $task->setStatus( $bottles . ' bottles of beer on the wall.' );
    }

    public function takeOneDownAndPassItAround( $beer_left )
    {
        // take our time with drinking it
        sleep( 5 );

        return $beer_left - 1;
    }

}

If you have multiple items to process in your task runner, you should only process one item at a time in your callback. Call the $task->setData() method to store information related to where you are at in your processing, and let the function return. If there is still time left for your task runner to do more work, your callback will be triggered again.

@Task Filters

There are some filters which you can use to change the way information about tasks is displayed.

mwp_task_title Filter the title
mwp_task_status_display Filter the displayed status
mwp_task_next_start_display Filter the displayed next start time
mwp_task_last_start_display Filter the displayed last start time

/**
 * Filter the task title
 * 
 * @param  string     $title      The existing task title
 * @param  object     $task       The task instance
 * @return string
 */
add_filter( 'mwp_task_title', function( $title, $task ) {
    switch( $task->action ) {
        case 'my_task_action':
            return 'Custom Task Title';
    }
    return $title;
});

/**
 * Filter the displayed task status
 * 
 * @param  string     $status     The existing task status text
 * @param  object     $task       The task instance
 * @return string
 */
add_filter( 'mwp_task_status_display', function( $status, $task ) {
    return $status;
});

/**
 * Filter the displayed task next start time
 * 
 * @param  string     $next_start  The existing next start text
 * @param  object     $task        The task instance
 * @return string
 */
add_filter( 'mwp_task_next_start_display', function( $next_start, $task ) {
    return $next_start;
});

/**
 * Filter the displayed task last start time
 * 
 * @param  string     $last_start   The existing last start text
 * @param  object     $task         The task instance
 * @return string
 */
add_filter( 'mwp_task_last_start_display', function( $last_start, $task ) {
    return $last_start;
});

@Completing A Task

If you want to indicate that your task is complete:

return $task->complete();

@Delaying A Task

If you want to postpone processing until a future date/time, or set up the next cycle for your task without telling the system to remove it, just set the next_start property on the task and return from the function. This will cause your task callback to be delayed until the next start time is reached.

// start back up in 24 hours
$task->next_start = time() + ( 60 * 60 * 24 );
return;

@Logging Task Info

Logging debug data and other information related to the status and running of your task can also be helpful, even in production. There is a convenient log() method on the task object that you can call to save a message to the task which can be viewed from the task details page in the wordpress admin.

/**
 * Save a log message
 *
 * @param   string          $message            The message to log
 */
public function log( $message )

/**
 * @MWP\WordPress\Action( for="my_task_callback" )
 */
public function taskCallback( $task )
{
    $task->log( 'Feeling lazy today.' );
    $task->complete();
}

@Circuit Breaker

The task runner has a built in circuit breaker designed to stop runaway tasks. It is designed to prevent the runner from getting caught in a never ending loop.

A triggered circuit breaker could be caused by a few different scenarios:

  • If your task callback fails to call $task->complete() when it has completed its workload.
  • If your task callback was registered incorrectly to its WordPress hook and is not actually being invoked.
  • If your task has a bug internally which is causing it to not progress through its workload.
  • If your task is performing very light duty work on a data set larger than 1000 items and it works its way through 1000 cycles on a single run.

For that last scenario, if you are expecting your task to routinely blow through 1000 cycles of work in a session, you can set the breaker back to zero on each iteration and effectively disable it.

$task->breaker = 0;
Was this article helpful to you? Yes No

How can we help?