From 8a043ea5bed84a30bf9cab935dde75ff541bb9fb Mon Sep 17 00:00:00 2001 From: Brendan Heywood Date: Mon, 28 Sep 2026 10:53:33 +1000 Subject: [PATCH 1/2] Document Task progress api --- docs/apis/subsystems/output/index.md | 2 + docs/apis/subsystems/task/index.md | 78 +++++++++++++++++++ .../apis/subsystems/output/index.md | 2 + .../version-4.5/apis/subsystems/task/index.md | 61 +++++++++++++++ .../apis/subsystems/output/index.md | 2 + .../version-5.0/apis/subsystems/task/index.md | 78 +++++++++++++++++++ .../apis/subsystems/output/index.md | 2 + .../version-5.1/apis/subsystems/task/index.md | 78 +++++++++++++++++++ .../apis/subsystems/output/index.md | 2 + .../version-5.2/apis/subsystems/task/index.md | 78 +++++++++++++++++++ 10 files changed, 383 insertions(+) diff --git a/docs/apis/subsystems/output/index.md b/docs/apis/subsystems/output/index.md index af26155198..afd6f1e6aa 100644 --- a/docs/apis/subsystems/output/index.md +++ b/docs/apis/subsystems/output/index.md @@ -505,6 +505,8 @@ $task->initialise_stored_progress(); // Creates a stored progress record, so the With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. + ## Reusing Output Classes in Web Services {/* #reusing-output-classes-in-web-services */} diff --git a/docs/apis/subsystems/task/index.md b/docs/apis/subsystems/task/index.md index 4689e0e5aa..43d62507d4 100644 --- a/docs/apis/subsystems/task/index.md +++ b/docs/apis/subsystems/task/index.md @@ -103,6 +103,84 @@ class my_task extends \core\task\scheduled_task { } ``` +### Reporting live progress {/* #reporting-live-progress */} + + + +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. + +```php +class my_task extends \core\task\scheduled_task { + + use \core\task\stored_progress_task_trait; + + public function execute() { + + // This simulates a specific count of iterations the task will do, e.g. x number of courses to loop through and do something. + $iterations = 100; + + // Updates the stored progress record with a start time. + $this->start_stored_progress(); + + for ($i = 1; $i <= $iterations; $i++) { + + // Here we just update and tell it which one we are on, and it will work out the percentage from those. + $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); + + } + + } + +} +``` + +Before the task has started running (for example, immediately after an adhoc task has been queued), you can call `initialise_stored_progress()` on the task instance to create the stored progress record in a "pending" state, so that it can be displayed on screen straight away. Note that an adhoc task has no database ID until it has been queued, so the task must be queued, and the returned ID set back on the task, before `initialise_stored_progress()` is called - otherwise its progress name won't match the one used when the task actually runs: + +```php +$task = new my_adhoc_task(); +$task->set_custom_data(['courseid' => $courseid]); + +$taskid = \core\task\manager::queue_adhoc_task($task); +if ($taskid) { + // The task's ID must be set before initialising the stored progress record, so + // that both use the same idnumber when the task later calls start_stored_progress(). + $task->set_id($taskid); + + // Creates a stored progress record, so the progress can be displayed in a "pending" state, before the task has actually run. + $task->initialise_stored_progress(); +} +``` + +#### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} + +Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. + +```php +// For an adhoc task, the idnumber includes the task's record ID, so that concurrent +// executions of the same adhoc task each have their own progress bar. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); + +// For a scheduled task, there is only ever one instance running at a time, so the +// idnumber is based on the class name alone. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); + +$bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); +if ($bar) { + // Renders the progress bar HTML, and queues up the `core/stored_progress` AMD + // module which polls the `core_output_poll_stored_progress` web service and + // updates the bar on screen until the task completes. + echo $bar->get_content(); +} else { + // There is no stored progress record, e.g. because the task has not started, or + // has already finished and been cleaned up. + echo get_string('nothingtodisplay'); +} +``` + +`get_content()` can be called from any page, at any time after the record has been created, including in a completely different request to the one that queued or ran the task - for example, an admin page which is refreshed and simply checks for the presence of a stored progress record matching a known idnumber. + +See the [Stored Progress Bars](../output/index.md#stored-progress-bars) section of the Output API documentation for more information, including how to poll and render the progress bar, and how to configure the polling interval. + ## For Administrators {/* #for-administrators */} Several tools exist for administrators: diff --git a/versioned_docs/version-4.5/apis/subsystems/output/index.md b/versioned_docs/version-4.5/apis/subsystems/output/index.md index efea08e417..4ea20bab4e 100644 --- a/versioned_docs/version-4.5/apis/subsystems/output/index.md +++ b/versioned_docs/version-4.5/apis/subsystems/output/index.md @@ -466,6 +466,8 @@ class stored_progress_scheduled_task_example extends \core\task\scheduled_task { With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. + ## See also {/* #see-also */} - [HTML Guidelines](https://docs.moodle.org/dev/HTML_Guidelines) diff --git a/versioned_docs/version-4.5/apis/subsystems/task/index.md b/versioned_docs/version-4.5/apis/subsystems/task/index.md index 4689e0e5aa..d6a07a352b 100644 --- a/versioned_docs/version-4.5/apis/subsystems/task/index.md +++ b/versioned_docs/version-4.5/apis/subsystems/task/index.md @@ -103,6 +103,67 @@ class my_task extends \core\task\scheduled_task { } ``` +### Reporting live progress {/* #reporting-live-progress */} + + + +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. + +```php +class my_task extends \core\task\scheduled_task { + + use \core\task\stored_progress_task_trait; + + public function execute() { + + // This simulates a specific count of iterations the task will do, e.g. x number of courses to loop through and do something. + $iterations = 100; + + // This creates the stored progress record for the named task. + $this->start_stored_progress(); + + for ($i = 1; $i <= $iterations; $i++) { + + // Here we just update and tell it which one we are on, and it will work out the percentage from those. + $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); + + } + + } + +} +``` + +#### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} + +Once a task has created a stored progress record (via `start_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. + +```php +// For an adhoc task, the idnumber includes the task's record ID, so that concurrent +// executions of the same adhoc task each have their own progress bar. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); + +// For a scheduled task, there is only ever one instance running at a time, so the +// idnumber is based on the class name alone. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); + +$bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); +if ($bar) { + // Renders the progress bar HTML, and queues up the `core/stored_progress` AMD + // module which polls the `core_output_poll_stored_progress` web service and + // updates the bar on screen until the task completes. + echo $bar->get_content(); +} else { + // There is no stored progress record, e.g. because the task has not started, or + // has already finished and been cleaned up. + echo get_string('nothingtodisplay'); +} +``` + +`get_content()` can be called from any page, at any time after the record has been created, including in a completely different request to the one that queued or ran the task - for example, an admin page which is refreshed and simply checks for the presence of a stored progress record matching a known idnumber. + +See the [Stored Progress Bars](../output/index.md#stored-progress-bars) section of the Output API documentation for more information, including how to poll and render the progress bar, and how to configure the polling interval. + ## For Administrators {/* #for-administrators */} Several tools exist for administrators: diff --git a/versioned_docs/version-5.0/apis/subsystems/output/index.md b/versioned_docs/version-5.0/apis/subsystems/output/index.md index 92a93e487d..cd051f322f 100644 --- a/versioned_docs/version-5.0/apis/subsystems/output/index.md +++ b/versioned_docs/version-5.0/apis/subsystems/output/index.md @@ -505,6 +505,8 @@ $task->initialise_stored_progress(); // Creates a stored progress record, so the With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. + ## See also {/* #see-also */} - [HTML Guidelines](https://docs.moodle.org/dev/HTML_Guidelines) diff --git a/versioned_docs/version-5.0/apis/subsystems/task/index.md b/versioned_docs/version-5.0/apis/subsystems/task/index.md index 4689e0e5aa..43d62507d4 100644 --- a/versioned_docs/version-5.0/apis/subsystems/task/index.md +++ b/versioned_docs/version-5.0/apis/subsystems/task/index.md @@ -103,6 +103,84 @@ class my_task extends \core\task\scheduled_task { } ``` +### Reporting live progress {/* #reporting-live-progress */} + + + +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. + +```php +class my_task extends \core\task\scheduled_task { + + use \core\task\stored_progress_task_trait; + + public function execute() { + + // This simulates a specific count of iterations the task will do, e.g. x number of courses to loop through and do something. + $iterations = 100; + + // Updates the stored progress record with a start time. + $this->start_stored_progress(); + + for ($i = 1; $i <= $iterations; $i++) { + + // Here we just update and tell it which one we are on, and it will work out the percentage from those. + $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); + + } + + } + +} +``` + +Before the task has started running (for example, immediately after an adhoc task has been queued), you can call `initialise_stored_progress()` on the task instance to create the stored progress record in a "pending" state, so that it can be displayed on screen straight away. Note that an adhoc task has no database ID until it has been queued, so the task must be queued, and the returned ID set back on the task, before `initialise_stored_progress()` is called - otherwise its progress name won't match the one used when the task actually runs: + +```php +$task = new my_adhoc_task(); +$task->set_custom_data(['courseid' => $courseid]); + +$taskid = \core\task\manager::queue_adhoc_task($task); +if ($taskid) { + // The task's ID must be set before initialising the stored progress record, so + // that both use the same idnumber when the task later calls start_stored_progress(). + $task->set_id($taskid); + + // Creates a stored progress record, so the progress can be displayed in a "pending" state, before the task has actually run. + $task->initialise_stored_progress(); +} +``` + +#### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} + +Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. + +```php +// For an adhoc task, the idnumber includes the task's record ID, so that concurrent +// executions of the same adhoc task each have their own progress bar. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); + +// For a scheduled task, there is only ever one instance running at a time, so the +// idnumber is based on the class name alone. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); + +$bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); +if ($bar) { + // Renders the progress bar HTML, and queues up the `core/stored_progress` AMD + // module which polls the `core_output_poll_stored_progress` web service and + // updates the bar on screen until the task completes. + echo $bar->get_content(); +} else { + // There is no stored progress record, e.g. because the task has not started, or + // has already finished and been cleaned up. + echo get_string('nothingtodisplay'); +} +``` + +`get_content()` can be called from any page, at any time after the record has been created, including in a completely different request to the one that queued or ran the task - for example, an admin page which is refreshed and simply checks for the presence of a stored progress record matching a known idnumber. + +See the [Stored Progress Bars](../output/index.md#stored-progress-bars) section of the Output API documentation for more information, including how to poll and render the progress bar, and how to configure the polling interval. + ## For Administrators {/* #for-administrators */} Several tools exist for administrators: diff --git a/versioned_docs/version-5.1/apis/subsystems/output/index.md b/versioned_docs/version-5.1/apis/subsystems/output/index.md index af26155198..afd6f1e6aa 100644 --- a/versioned_docs/version-5.1/apis/subsystems/output/index.md +++ b/versioned_docs/version-5.1/apis/subsystems/output/index.md @@ -505,6 +505,8 @@ $task->initialise_stored_progress(); // Creates a stored progress record, so the With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. + ## Reusing Output Classes in Web Services {/* #reusing-output-classes-in-web-services */} diff --git a/versioned_docs/version-5.1/apis/subsystems/task/index.md b/versioned_docs/version-5.1/apis/subsystems/task/index.md index 4689e0e5aa..43d62507d4 100644 --- a/versioned_docs/version-5.1/apis/subsystems/task/index.md +++ b/versioned_docs/version-5.1/apis/subsystems/task/index.md @@ -103,6 +103,84 @@ class my_task extends \core\task\scheduled_task { } ``` +### Reporting live progress {/* #reporting-live-progress */} + + + +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. + +```php +class my_task extends \core\task\scheduled_task { + + use \core\task\stored_progress_task_trait; + + public function execute() { + + // This simulates a specific count of iterations the task will do, e.g. x number of courses to loop through and do something. + $iterations = 100; + + // Updates the stored progress record with a start time. + $this->start_stored_progress(); + + for ($i = 1; $i <= $iterations; $i++) { + + // Here we just update and tell it which one we are on, and it will work out the percentage from those. + $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); + + } + + } + +} +``` + +Before the task has started running (for example, immediately after an adhoc task has been queued), you can call `initialise_stored_progress()` on the task instance to create the stored progress record in a "pending" state, so that it can be displayed on screen straight away. Note that an adhoc task has no database ID until it has been queued, so the task must be queued, and the returned ID set back on the task, before `initialise_stored_progress()` is called - otherwise its progress name won't match the one used when the task actually runs: + +```php +$task = new my_adhoc_task(); +$task->set_custom_data(['courseid' => $courseid]); + +$taskid = \core\task\manager::queue_adhoc_task($task); +if ($taskid) { + // The task's ID must be set before initialising the stored progress record, so + // that both use the same idnumber when the task later calls start_stored_progress(). + $task->set_id($taskid); + + // Creates a stored progress record, so the progress can be displayed in a "pending" state, before the task has actually run. + $task->initialise_stored_progress(); +} +``` + +#### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} + +Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. + +```php +// For an adhoc task, the idnumber includes the task's record ID, so that concurrent +// executions of the same adhoc task each have their own progress bar. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); + +// For a scheduled task, there is only ever one instance running at a time, so the +// idnumber is based on the class name alone. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); + +$bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); +if ($bar) { + // Renders the progress bar HTML, and queues up the `core/stored_progress` AMD + // module which polls the `core_output_poll_stored_progress` web service and + // updates the bar on screen until the task completes. + echo $bar->get_content(); +} else { + // There is no stored progress record, e.g. because the task has not started, or + // has already finished and been cleaned up. + echo get_string('nothingtodisplay'); +} +``` + +`get_content()` can be called from any page, at any time after the record has been created, including in a completely different request to the one that queued or ran the task - for example, an admin page which is refreshed and simply checks for the presence of a stored progress record matching a known idnumber. + +See the [Stored Progress Bars](../output/index.md#stored-progress-bars) section of the Output API documentation for more information, including how to poll and render the progress bar, and how to configure the polling interval. + ## For Administrators {/* #for-administrators */} Several tools exist for administrators: diff --git a/versioned_docs/version-5.2/apis/subsystems/output/index.md b/versioned_docs/version-5.2/apis/subsystems/output/index.md index af26155198..afd6f1e6aa 100644 --- a/versioned_docs/version-5.2/apis/subsystems/output/index.md +++ b/versioned_docs/version-5.2/apis/subsystems/output/index.md @@ -505,6 +505,8 @@ $task->initialise_stored_progress(); // Creates a stored progress record, so the With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. + ## Reusing Output Classes in Web Services {/* #reusing-output-classes-in-web-services */} diff --git a/versioned_docs/version-5.2/apis/subsystems/task/index.md b/versioned_docs/version-5.2/apis/subsystems/task/index.md index 4689e0e5aa..43d62507d4 100644 --- a/versioned_docs/version-5.2/apis/subsystems/task/index.md +++ b/versioned_docs/version-5.2/apis/subsystems/task/index.md @@ -103,6 +103,84 @@ class my_task extends \core\task\scheduled_task { } ``` +### Reporting live progress {/* #reporting-live-progress */} + + + +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. + +```php +class my_task extends \core\task\scheduled_task { + + use \core\task\stored_progress_task_trait; + + public function execute() { + + // This simulates a specific count of iterations the task will do, e.g. x number of courses to loop through and do something. + $iterations = 100; + + // Updates the stored progress record with a start time. + $this->start_stored_progress(); + + for ($i = 1; $i <= $iterations; $i++) { + + // Here we just update and tell it which one we are on, and it will work out the percentage from those. + $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); + + } + + } + +} +``` + +Before the task has started running (for example, immediately after an adhoc task has been queued), you can call `initialise_stored_progress()` on the task instance to create the stored progress record in a "pending" state, so that it can be displayed on screen straight away. Note that an adhoc task has no database ID until it has been queued, so the task must be queued, and the returned ID set back on the task, before `initialise_stored_progress()` is called - otherwise its progress name won't match the one used when the task actually runs: + +```php +$task = new my_adhoc_task(); +$task->set_custom_data(['courseid' => $courseid]); + +$taskid = \core\task\manager::queue_adhoc_task($task); +if ($taskid) { + // The task's ID must be set before initialising the stored progress record, so + // that both use the same idnumber when the task later calls start_stored_progress(). + $task->set_id($taskid); + + // Creates a stored progress record, so the progress can be displayed in a "pending" state, before the task has actually run. + $task->initialise_stored_progress(); +} +``` + +#### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} + +Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. + +```php +// For an adhoc task, the idnumber includes the task's record ID, so that concurrent +// executions of the same adhoc task each have their own progress bar. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); + +// For a scheduled task, there is only ever one instance running at a time, so the +// idnumber is based on the class name alone. +$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); + +$bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); +if ($bar) { + // Renders the progress bar HTML, and queues up the `core/stored_progress` AMD + // module which polls the `core_output_poll_stored_progress` web service and + // updates the bar on screen until the task completes. + echo $bar->get_content(); +} else { + // There is no stored progress record, e.g. because the task has not started, or + // has already finished and been cleaned up. + echo get_string('nothingtodisplay'); +} +``` + +`get_content()` can be called from any page, at any time after the record has been created, including in a completely different request to the one that queued or ran the task - for example, an admin page which is refreshed and simply checks for the presence of a stored progress record matching a known idnumber. + +See the [Stored Progress Bars](../output/index.md#stored-progress-bars) section of the Output API documentation for more information, including how to poll and render the progress bar, and how to configure the polling interval. + ## For Administrators {/* #for-administrators */} Several tools exist for administrators: From 8bdeba8716fb300b088e2b209992bc639f9892bb Mon Sep 17 00:00:00 2001 From: Brendan Heywood Date: Mon, 28 Sep 2026 23:59:36 +1000 Subject: [PATCH 2/2] Fix up --- docs/apis/subsystems/output/index.md | 10 +++---- docs/apis/subsystems/task/index.md | 28 ++++++++++--------- .../apis/subsystems/output/index.md | 2 +- .../version-4.5/apis/subsystems/task/index.md | 28 ++++++++++--------- .../apis/subsystems/output/index.md | 2 +- .../version-5.0/apis/subsystems/task/index.md | 28 ++++++++++--------- .../apis/subsystems/output/index.md | 2 +- .../version-5.1/apis/subsystems/task/index.md | 28 ++++++++++--------- .../apis/subsystems/output/index.md | 2 +- .../version-5.2/apis/subsystems/task/index.md | 28 ++++++++++--------- 10 files changed, 84 insertions(+), 74 deletions(-) diff --git a/docs/apis/subsystems/output/index.md b/docs/apis/subsystems/output/index.md index afd6f1e6aa..01599ed26e 100644 --- a/docs/apis/subsystems/output/index.md +++ b/docs/apis/subsystems/output/index.md @@ -488,15 +488,15 @@ class stored_progress_scheduled_task_example extends \core\task\scheduled_task { for ($i = 1; $i <= $iterations; $i++) { // Here we just update and tell it which one we are on and it will work out % from those. - $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); + $this->progress->update($i, $iterations, get_string('processingitem', 'mod_yourplugin', [ + 'current' => $i, + 'total' => $iterations, + ])); sleep(1); - } return true; - } - } $task = new stored_progress_scheduled_task_example(); @@ -505,7 +505,7 @@ $task->initialise_stored_progress(); // Creates a stored progress record, so the With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. -The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete stored progress records with a `lastupdate` older than 24 hours. ## Reusing Output Classes in Web Services {/* #reusing-output-classes-in-web-services */} diff --git a/docs/apis/subsystems/task/index.md b/docs/apis/subsystems/task/index.md index 43d62507d4..b254523271 100644 --- a/docs/apis/subsystems/task/index.md +++ b/docs/apis/subsystems/task/index.md @@ -107,7 +107,7 @@ class my_task extends \core\task\scheduled_task { -For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/public/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. ```php class my_task extends \core\task\scheduled_task { @@ -125,12 +125,12 @@ class my_task extends \core\task\scheduled_task { for ($i = 1; $i <= $iterations; $i++) { // Here we just update and tell it which one we are on, and it will work out the percentage from those. - $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); - + $this->progress->update($i, $iterations, get_string('processingitem', 'mod_yourplugin', [ + 'current' => $i, + 'total' => $iterations, + ])); } - } - } ``` @@ -153,16 +153,18 @@ if ($taskid) { #### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} -Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. +Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/public/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. ```php -// For an adhoc task, the idnumber includes the task's record ID, so that concurrent -// executions of the same adhoc task each have their own progress bar. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); - -// For a scheduled task, there is only ever one instance running at a time, so the -// idnumber is based on the class name alone. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +if ($task instanceof \core\task\adhoc_task) { + // For an adhoc task, the idnumber includes the task's record ID, so that concurrent + // executions of the same adhoc task each have their own progress bar. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); +} else { + // For a scheduled task, there is only ever one instance running at a time, so the + // idnumber is based on the class name alone. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +} $bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); if ($bar) { diff --git a/versioned_docs/version-4.5/apis/subsystems/output/index.md b/versioned_docs/version-4.5/apis/subsystems/output/index.md index 4ea20bab4e..d9470f0d48 100644 --- a/versioned_docs/version-4.5/apis/subsystems/output/index.md +++ b/versioned_docs/version-4.5/apis/subsystems/output/index.md @@ -466,7 +466,7 @@ class stored_progress_scheduled_task_example extends \core\task\scheduled_task { With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. -The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete stored progress records with a `lastupdate` older than 24 hours. ## See also {/* #see-also */} diff --git a/versioned_docs/version-4.5/apis/subsystems/task/index.md b/versioned_docs/version-4.5/apis/subsystems/task/index.md index d6a07a352b..624fcca333 100644 --- a/versioned_docs/version-4.5/apis/subsystems/task/index.md +++ b/versioned_docs/version-4.5/apis/subsystems/task/index.md @@ -107,7 +107,7 @@ class my_task extends \core\task\scheduled_task { -For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/MOODLE_405_STABLE/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. ```php class my_task extends \core\task\scheduled_task { @@ -125,27 +125,29 @@ class my_task extends \core\task\scheduled_task { for ($i = 1; $i <= $iterations; $i++) { // Here we just update and tell it which one we are on, and it will work out the percentage from those. - $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); - + $this->progress->update($i, $iterations, get_string('processingitem', 'mod_yourplugin', [ + 'current' => $i, + 'total' => $iterations, + ])); } - } - } ``` #### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} -Once a task has created a stored progress record (via `start_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. +Once a task has created a stored progress record (via `start_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/MOODLE_405_STABLE/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. ```php -// For an adhoc task, the idnumber includes the task's record ID, so that concurrent -// executions of the same adhoc task each have their own progress bar. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); - -// For a scheduled task, there is only ever one instance running at a time, so the -// idnumber is based on the class name alone. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +if ($task instanceof \core\task\adhoc_task) { + // For an adhoc task, the idnumber includes the task's record ID, so that concurrent + // executions of the same adhoc task each have their own progress bar. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); +} else { + // For a scheduled task, there is only ever one instance running at a time, so the + // idnumber is based on the class name alone. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +} $bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); if ($bar) { diff --git a/versioned_docs/version-5.0/apis/subsystems/output/index.md b/versioned_docs/version-5.0/apis/subsystems/output/index.md index cd051f322f..20200b0734 100644 --- a/versioned_docs/version-5.0/apis/subsystems/output/index.md +++ b/versioned_docs/version-5.0/apis/subsystems/output/index.md @@ -505,7 +505,7 @@ $task->initialise_stored_progress(); // Creates a stored progress record, so the With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. -The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete stored progress records with a `lastupdate` older than 24 hours. ## See also {/* #see-also */} diff --git a/versioned_docs/version-5.0/apis/subsystems/task/index.md b/versioned_docs/version-5.0/apis/subsystems/task/index.md index 43d62507d4..cbc5fe8fad 100644 --- a/versioned_docs/version-5.0/apis/subsystems/task/index.md +++ b/versioned_docs/version-5.0/apis/subsystems/task/index.md @@ -107,7 +107,7 @@ class my_task extends \core\task\scheduled_task { -For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/MOODLE_500_STABLE/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. ```php class my_task extends \core\task\scheduled_task { @@ -125,12 +125,12 @@ class my_task extends \core\task\scheduled_task { for ($i = 1; $i <= $iterations; $i++) { // Here we just update and tell it which one we are on, and it will work out the percentage from those. - $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); - + $this->progress->update($i, $iterations, get_string('processingitem', 'mod_yourplugin', [ + 'current' => $i, + 'total' => $iterations, + ])); } - } - } ``` @@ -153,16 +153,18 @@ if ($taskid) { #### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} -Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. +Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/MOODLE_500_STABLE/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. ```php -// For an adhoc task, the idnumber includes the task's record ID, so that concurrent -// executions of the same adhoc task each have their own progress bar. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); - -// For a scheduled task, there is only ever one instance running at a time, so the -// idnumber is based on the class name alone. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +if ($task instanceof \core\task\adhoc_task) { + // For an adhoc task, the idnumber includes the task's record ID, so that concurrent + // executions of the same adhoc task each have their own progress bar. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); +} else { + // For a scheduled task, there is only ever one instance running at a time, so the + // idnumber is based on the class name alone. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +} $bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); if ($bar) { diff --git a/versioned_docs/version-5.1/apis/subsystems/output/index.md b/versioned_docs/version-5.1/apis/subsystems/output/index.md index afd6f1e6aa..2fab3e29e2 100644 --- a/versioned_docs/version-5.1/apis/subsystems/output/index.md +++ b/versioned_docs/version-5.1/apis/subsystems/output/index.md @@ -505,7 +505,7 @@ $task->initialise_stored_progress(); // Creates a stored progress record, so the With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. -The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete stored progress records with a `lastupdate` older than 24 hours. ## Reusing Output Classes in Web Services {/* #reusing-output-classes-in-web-services */} diff --git a/versioned_docs/version-5.1/apis/subsystems/task/index.md b/versioned_docs/version-5.1/apis/subsystems/task/index.md index 43d62507d4..ec1427dd17 100644 --- a/versioned_docs/version-5.1/apis/subsystems/task/index.md +++ b/versioned_docs/version-5.1/apis/subsystems/task/index.md @@ -107,7 +107,7 @@ class my_task extends \core\task\scheduled_task { -For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/MOODLE_501_STABLE/public/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. ```php class my_task extends \core\task\scheduled_task { @@ -125,12 +125,12 @@ class my_task extends \core\task\scheduled_task { for ($i = 1; $i <= $iterations; $i++) { // Here we just update and tell it which one we are on, and it will work out the percentage from those. - $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); - + $this->progress->update($i, $iterations, get_string('processingitem', 'mod_yourplugin', [ + 'current' => $i, + 'total' => $iterations, + ])); } - } - } ``` @@ -153,16 +153,18 @@ if ($taskid) { #### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} -Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. +Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/MOODLE_501_STABLE/public/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. ```php -// For an adhoc task, the idnumber includes the task's record ID, so that concurrent -// executions of the same adhoc task each have their own progress bar. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); - -// For a scheduled task, there is only ever one instance running at a time, so the -// idnumber is based on the class name alone. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +if ($task instanceof \core\task\adhoc_task) { + // For an adhoc task, the idnumber includes the task's record ID, so that concurrent + // executions of the same adhoc task each have their own progress bar. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); +} else { + // For a scheduled task, there is only ever one instance running at a time, so the + // idnumber is based on the class name alone. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +} $bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); if ($bar) { diff --git a/versioned_docs/version-5.2/apis/subsystems/output/index.md b/versioned_docs/version-5.2/apis/subsystems/output/index.md index afd6f1e6aa..2fab3e29e2 100644 --- a/versioned_docs/version-5.2/apis/subsystems/output/index.md +++ b/versioned_docs/version-5.2/apis/subsystems/output/index.md @@ -505,7 +505,7 @@ $task->initialise_stored_progress(); // Creates a stored progress record, so the With the stored progress bars, you can update the progress either via iterations, by passing in the total amount expected and then the current iteration, using `->update()`(see: previous example), this will calculate the percentage complete for you. Or you can use `->update_full()` to manually set the percentage complete. -The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete any stored progress records which have not been updated within the last 24 hours. +The web page polls for updates via the `core_output_poll_stored_progress` web service, at an interval controlled by the `$CFG->progresspollinterval` setting (in seconds, default `5`). A scheduled task, `\core\task\stored_progress_bar_cleanup_task`, runs daily to delete stored progress records with a `lastupdate` older than 24 hours. ## Reusing Output Classes in Web Services {/* #reusing-output-classes-in-web-services */} diff --git a/versioned_docs/version-5.2/apis/subsystems/task/index.md b/versioned_docs/version-5.2/apis/subsystems/task/index.md index 43d62507d4..70b7a1a904 100644 --- a/versioned_docs/version-5.2/apis/subsystems/task/index.md +++ b/versioned_docs/version-5.2/apis/subsystems/task/index.md @@ -107,7 +107,7 @@ class my_task extends \core\task\scheduled_task { -For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/main/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. +For long-running scheduled or adhoc tasks, you can report live progress by using the `\core\task\stored_progress_task_trait` trait. This stores the task's progress in the database, and allows it to be polled for and rendered as a progress bar on any page in Moodle (for example, on the [`admin/tool/task`](https://github.com/moodle/moodle/tree/MOODLE_502_STABLE/public/admin/tool/task) "Tasks running now" page), via the `core_output_poll_stored_progress` web service. ```php class my_task extends \core\task\scheduled_task { @@ -125,12 +125,12 @@ class my_task extends \core\task\scheduled_task { for ($i = 1; $i <= $iterations; $i++) { // Here we just update and tell it which one we are on, and it will work out the percentage from those. - $this->progress->update($i, $iterations, 'i am at ' . $i . ' of ' . $iterations); - + $this->progress->update($i, $iterations, get_string('processingitem', 'mod_yourplugin', [ + 'current' => $i, + 'total' => $iterations, + ])); } - } - } ``` @@ -153,16 +153,18 @@ if ($taskid) { #### Displaying the progress on a page {/* #displaying-the-progress-on-a-page */} -Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/main/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. +Once a task has created a stored progress record (either via `start_stored_progress()` or `initialise_stored_progress()`), any page can load it by its unique idnumber and render it. The idnumber is generated by `stored_progress_bar::convert_to_idnumber()`, using the task's class name and, for adhoc tasks, its record ID. This is exactly the approach used by the "Tasks running now" report in [`admin/tool/task`](https://github.com/moodle/moodle/blob/MOODLE_502_STABLE/public/admin/tool/task/classes/running_tasks_table.php), which shows the live progress of every currently-running scheduled and adhoc task. ```php -// For an adhoc task, the idnumber includes the task's record ID, so that concurrent -// executions of the same adhoc task each have their own progress bar. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); - -// For a scheduled task, there is only ever one instance running at a time, so the -// idnumber is based on the class name alone. -$idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +if ($task instanceof \core\task\adhoc_task) { + // For an adhoc task, the idnumber includes the task's record ID, so that concurrent + // executions of the same adhoc task each have their own progress bar. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_adhoc_task::class, $task->get_id()); +} else { + // For a scheduled task, there is only ever one instance running at a time, so the + // idnumber is based on the class name alone. + $idnumber = \core\output\stored_progress_bar::convert_to_idnumber(my_task::class); +} $bar = \core\output\stored_progress_bar::get_by_idnumber($idnumber); if ($bar) {