MDL-28505 Backup: Asynchronous backup and restore

This patch adds asynchronous backup and restore functionality
to Moodle. This is an optional feature and is not enabled by
default. It can be enabled by site administrators.
Asynchronous backup and restores are actioned by the Moodle
adhoc task API. The progress of backup and restores is
displayedin the Moodle UI.  Users can also be sent a message
when a backup or restore operation completes via the
Moodle messaging API.
This commit is contained in:
Matt Porritt
2019-04-09 00:15:42 +00:00
parent 9d4f4f0051
commit 2cd901a4e7
35 changed files with 2459 additions and 115 deletions
+22 -7
View File
@@ -53,7 +53,11 @@ class restore_controller extends base_controller {
/** @var restore_plan */
protected $plan; // Restore execution plan
protected $execution; // inmediate/delayed
/**
* Immediate/delayed execution type.
* @var integer
*/
protected $execution;
protected $executiontime; // epoch time when we want the restore to be executed (requires cron to run)
protected $checksum; // Cache @checksumable results for lighter @is_checksum_correct() uses
@@ -88,7 +92,6 @@ class restore_controller extends base_controller {
// Apply some defaults
$this->type = '';
$this->format = backup::FORMAT_UNKNOWN;
$this->execution = backup::EXECUTION_INMEDIATE;
$this->operation = backup::OPERATION_RESTORE;
$this->executiontime = 0;
$this->samesite = false;
@@ -110,6 +113,13 @@ class restore_controller extends base_controller {
// Default logger chain (based on interactive/execution)
$this->logger = backup_factory::get_logger_chain($this->interactive, $this->execution, $this->restoreid);
// Set execution based on backup mode.
if ($mode == backup::MODE_ASYNC) {
$this->execution = backup::EXECUTION_DELAYED;
} else {
$this->execution = backup::EXECUTION_INMEDIATE;
}
// By default there is no progress reporter unless you specify one so it
// can be used during loading of the plan.
if ($progress) {
@@ -119,7 +129,7 @@ class restore_controller extends base_controller {
}
$this->progress->start_progress('Constructing restore_controller');
// Instantiate the output_controller singleton and active it if interactive and inmediate
// Instantiate the output_controller singleton and active it if interactive and immediate.
$oc = output_controller::get_instance();
if ($this->interactive == backup::INTERACTIVE_YES && $this->execution == backup::EXECUTION_INMEDIATE) {
$oc->set_active(true);
@@ -198,7 +208,8 @@ class restore_controller extends base_controller {
// TODO: Check it's a correct status.
$this->status = $status;
// Ensure that, once set to backup::STATUS_AWAITING | STATUS_NEED_PRECHECK, controller is stored in DB.
if ($status == backup::STATUS_AWAITING || $status == backup::STATUS_NEED_PRECHECK) {
// Also save if executing so we can better track progress.
if ($status == backup::STATUS_AWAITING || $status == backup::STATUS_NEED_PRECHECK || $status == backup::STATUS_EXECUTING) {
$this->save_controller();
$tbc = self::load_controller($this->restoreid);
$this->logger = $tbc->logger; // wakeup loggers
@@ -208,14 +219,18 @@ class restore_controller extends base_controller {
// If the operation has ended without error (backup::STATUS_FINISHED_OK)
// proceed by cleaning the object from database. MDL-29262.
$this->save_controller(false, true);
} else if ($status == backup::STATUS_FINISHED_ERR) {
// If the operation has ended with an error save the controller
// preserving the object in the database. We may want it for debugging.
$this->save_controller();
}
}
public function set_execution($execution, $executiontime = 0) {
$this->log('setting controller execution', backup::LOG_DEBUG);
// TODO: Check valid execution mode
// TODO: Check time in future
// TODO: Check time = 0 if inmediate
// TODO: Check valid execution mode.
// TODO: Check time in future.
// TODO: Check time = 0 if immediate.
$this->execution = $execution;
$this->executiontime = $executiontime;