Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Task API: Difference between revisions

From MoodleDocs
No edit summary
Line 142: Line 142:


== Caches ==
== Caches ==
There is one special case that needs to be considered with this new system. If a particular scheduled or adhoc task runs for a long time and updates many DB records - particularly something related to enrolment - the next task in the queue may suffer because various API's in moodle use static caching to speed up requests, but assume that the data will not change much between the start and end of the request. In this case, you can force the cron to exit after running a task that has done many DB updates. The next cron will be run in the next minute, and will have all static caches cleared because it's a new process. Do to this call \core\task\manager::clear_static_caches();
There is one special case that needs to be considered with this new system. If a particular scheduled or adhoc task runs for a long time and updates many DB records - particularly something related to enrolment - the next task in the queue may suffer because various API's in moodle use static caching to speed up requests, but assume that the data will not change much between the start and end of the request. In this case, you can force the cron to exit after running a task that has done many DB updates. The next cron will be run in the next minute, and will have all static caches cleared because it's a new process. To do this call \core\task\manager::clear_static_caches();


== Security ==
== Security ==

Revision as of 03:26, 26 May 2014

Moodle 2.7


Task
Project state Integrated
Tracker issue MDL-25505
Discussion https://moodle.org/mod/forum/discuss.php?d=229139
Assignee Damyon


Tasks

A task is a unit of work that needs to be done later. Good uses for tasks:

  • Run a slow operation in the background
  • Run a maintenance task on a regular schedule

In general any operation that takes more than a few seconds should be a candidate for a task.

Benefits

  • Better user experience (give them feedback immediately, that their task has been queued)
  • Prevent browser timeouts
  • Better performance for clusters (tasks can be run on separate, non-webserving cluster node, tasks can run in parallel)
  • Failed tasks will be retried
  • A better user interface will prevent users queuing multiple tasks, because they thought it had "got stuck".

Types of task

Scheduled tasks

Scheduled tasks are tasks that will run on a regular schedule. A default schedule can be set, but admins have the ability to change the default schedule if required. Note: Tasks will only run as often as cron is run in Moodle. In 2.7 it is recommended to run cron once per minute to get the benefit from the new task scheduling (don't worry - it will do much less work each time it runs).

Adhoc tasks

Adhoc tasks are for when you need to queue something to run in the background immediately. Adhoc tasks can contain custom data, specific to this specific instance of the task.

Usage

Scheduled task usage

Scheduled tasks are created by subclassing \core\task\scheduled_task. They also require an entry in "db/tasks.php" for your plugin.

1. Create a subclass of \core\task\scheduled_task that contains your code to run in a schedule.

class cut_my_toe_nails extends \core\task\scheduled_task {      
    public function get_name() {
        // Shown in admin screens
        return get_string('cutmytoenails', 'mod_hygene');
    }
                                                                     
    public function execute() {       
        // apply fungus cream
        // apply chainsaw
        // apply olive oil
    }                                                                                                                               
} 

2. Create entry in db/tasks.php for your plugin:

$tasks = array(                                                                                                                     
    array(                                                                                                                          
        'classname' => 'mod_hygene\task\cut_my_toe_nails',                                                                            
        'blocking' => 0,                                                                                                            
        'minute' => '*',                                                                                                            
        'hour' => '*',                                                                                                              
        'day' => '*',                                                                                                               
        'dayofweek' => '*',                                                                                                         
        'month' => '1,6'                                                                                                              
    )
);

The field required in the db/tasks.php file are:

  • classname - the fully namespaced classname of your task. This needs to comply with the autoloading rules.
  • blocking - if this is set to 1, no other scheduled task will run at the same time as this task. Do not set this to 1 unless you really need it as it will impact the performance of the task queue.
  • minute, hour, day, dayofweek, month - This is the default schedule for running the task. The syntax matches the syntax of unix cron.

Cron syntax examples

  • day - Day of month field for task schedule.
    • "*" - Every day
    • "*/2" - Every 2nd day
    • "1" - The first of every month
    • "1,15" - The first and fifteenth of every month
  • dayofweek - Day of week field for task schedule.
    • "*" - Every day
    • "0" - Every Sunday
    • "6" - Every Saturday
    • "1,5" - Every Monday and Friday
  • hour - Hour field for task schedule.
    • "*" - Every hour
    • "*/2" - Every 2 hours
    • "2-10" - Every hour from 2am until 10am (inclusive)
    • "2,6,9" - 2am, 6am and 9am
  • minute - Minute field for task schedule.
    • "*" - Every minute
    • "*/5" - Every 5 minutes
    • "2-10" - Every minute between 2 and 10 minutes past the hour (inclusive)
    • "2,6,9" - 2, 6 and 9 minutes past the hour
  • month - Month field for task schedule.
    • "*" - Every month
    • "*/2" - Every second month
    • "1" - Every January
    • "1,5" - Every January and May

Adhoc task usage

This is even easier than scheduled tasks.

1. Create a subclass of \core\task\adhoc_task that contains your code to run in the background.


class take_over_the_world extends \core\task\adhoc_task {                                                                           
    public function execute() {       
        // gain 100,000,000 friends on facebook.
        // crash the stock market.
        // run for president.
    }                                                                                                                               
} 
                                      

2. Create an instance of the task and queue it (adding custom data if required).

   // create the instance
   $domination = new take_over_the_world();
   // set blocking if required (it probably isn't)
   // $domination->set_blocking(true);
   // add custom data
   $domination->set_custom_data(array(
       'plansfortomorrownight' => 'The same thing we do every night, Pinky!'
   ));

   // queue it
   \core\task\manager::queue_adhoc_task($domination);

   // profit

3. There is no 3.

Failures

A task, either scheduled or adhoc can sometimes fail. An example would be updating an RSS field when the network is temporarily down. This is handled by the task system automatically - all the failing task needs to do is throw an exception. The task will be retried after 1 minute. If the task keeps failing, the retry algorithm will add more time between each successive attempts up to a max of 24 hours.

Caches

There is one special case that needs to be considered with this new system. If a particular scheduled or adhoc task runs for a long time and updates many DB records - particularly something related to enrolment - the next task in the queue may suffer because various API's in moodle use static caching to speed up requests, but assume that the data will not change much between the start and end of the request. In this case, you can force the cron to exit after running a task that has done many DB updates. The next cron will be run in the next minute, and will have all static caches cleared because it's a new process. To do this call \core\task\manager::clear_static_caches();

Security

When scheduling a task to run in the background - or creating a scheduled task, the task will run in the context of the cron user (see "cron_setup_user()"). If you need to perform access checks in your background task, you should pass the userid/context in custom_data and then pass that userid to the access check functions ("require_capability('moodle/course:update', $context, $userid)").

Legacy cron

The older syntax of cron.php or modname_cron() is still supported - but is not as good as this new API. This is because:

  • the legacy cron functions run serially - a long running cron in one plugin will hold up the other plugins crons
  • the legacy cron functions are fragile - a failure in one cron in one plugin will prevent the cron in other functions from running at all
  • the scheduling cannot be changed by admins

For Admins

Admins have a new screen where they can adjust the schedules for any scheduled task. They can also reset any scheduled task to it's default schedule. Screenshot of admin page

Specification

The specification for this feature is here: https://docs.moodle.org/dev/Scheduled_Tasks_Proposal