MDL-42039 Restore: Add progress reporting to directory deletion

Deleting directories at the end of backup can take a long time if
there are many directories (potentially up to 65536 file
directories). This change reports progress while deleting
directories to avoid timeout.
This commit is contained in:
sam marshall 2013-09-30 13:06:42 +01:00 committed by Damyon Wiese
parent 37ff843d7d
commit 1cd39657b5
3 changed files with 52 additions and 14 deletions

View File

@ -34,10 +34,13 @@ defined('MOODLE_INTERNAL') || die();
class create_and_clean_temp_stuff extends backup_execution_step {
protected function define_execution() {
$progress = $this->task->get_progress();
$progress->start_progress('Deleting backup directories');
backup_helper::check_and_create_backup_dir($this->get_backupid());// Create backup temp dir
backup_helper::clear_backup_dir($this->get_backupid()); // Empty temp dir, just in case
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60)); // Delete > 4 hours temp dirs
backup_helper::clear_backup_dir($this->get_backupid(), $progress); // Empty temp dir, just in case
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60), $progress); // Delete > 4 hours temp dirs
backup_controller_dbops::create_backup_ids_temp_table($this->get_backupid()); // Create ids temp table
$progress->end_progress();
}
}
@ -61,7 +64,10 @@ class drop_and_clean_temp_stuff extends backup_execution_step {
// 1) If $CFG->keeptempdirectoriesonbackup is not enabled
// 2) If backup temp dir deletion has been marked to be avoided
if (empty($CFG->keeptempdirectoriesonbackup) && !$this->skipcleaningtempdir) {
backup_helper::delete_backup_dir($this->get_backupid()); // Empty backup dir
$progress = $this->task->get_progress();
$progress->start_progress('Deleting backup dir');
backup_helper::delete_backup_dir($this->get_backupid(), $progress); // Empty backup dir
$progress->end_progress();
}
}

View File

@ -65,10 +65,13 @@ class restore_drop_and_clean_temp_stuff extends restore_execution_step {
protected function define_execution() {
global $CFG;
restore_controller_dbops::drop_restore_temp_tables($this->get_restoreid()); // Drop ids temp table
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60)); // Delete > 4 hours temp dirs
$progress = $this->task->get_progress();
$progress->start_progress('Deleting backup dir');
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60), $progress); // Delete > 4 hours temp dirs
if (empty($CFG->keeptempdirectoriesonbackup)) { // Conditionally
backup_helper::delete_backup_dir($this->task->get_tempdir()); // Empty restore dir
backup_helper::delete_backup_dir($this->task->get_tempdir(), $progress); // Empty restore dir
}
$progress->end_progress();
}
}

View File

@ -41,10 +41,16 @@ abstract class backup_helper {
/**
* Given one backupid, ensure its temp dir is completely empty
*
* If supplied, progress object should be ready to receive indeterminate
* progress reports.
*
* @param string $backupid Backup id
* @param core_backup_progress $progress Optional progress reporting object
*/
static public function clear_backup_dir($backupid) {
static public function clear_backup_dir($backupid, core_backup_progress $progress = null) {
global $CFG;
if (!self::delete_dir_contents($CFG->tempdir . '/backup/' . $backupid)) {
if (!self::delete_dir_contents($CFG->tempdir . '/backup/' . $backupid, '', $progress)) {
throw new backup_helper_exception('cannot_empty_backup_temp_dir');
}
return true;
@ -52,10 +58,16 @@ abstract class backup_helper {
/**
* Given one backupid, delete completely its temp dir
*
* If supplied, progress object should be ready to receive indeterminate
* progress reports.
*
* @param string $backupid Backup id
* @param core_backup_progress $progress Optional progress reporting object
*/
static public function delete_backup_dir($backupid) {
static public function delete_backup_dir($backupid, core_backup_progress $progress = null) {
global $CFG;
self::clear_backup_dir($backupid);
self::clear_backup_dir($backupid, $progress);
return rmdir($CFG->tempdir . '/backup/' . $backupid);
}
@ -63,10 +75,21 @@ abstract class backup_helper {
* Given one fullpath to directory, delete its contents recursively
* Copied originally from somewhere in the net.
* TODO: Modernise this
*
* If supplied, progress object should be ready to receive indeterminate
* progress reports.
*
* @param string $dir Directory to delete
* @param string $excludedir Exclude this directory
* @param core_backup_progress $progress Optional progress reporting object
*/
static public function delete_dir_contents($dir, $excludeddir='') {
static public function delete_dir_contents($dir, $excludeddir='', core_backup_progress $progress = null) {
global $CFG;
if ($progress) {
$progress->progress();
}
if (!is_dir($dir)) {
// if we've been given a directory that doesn't exist yet, return true.
// this happens when we're trying to clear out a course that has only just
@ -108,7 +131,7 @@ abstract class backup_helper {
// Empty sub directories and then remove the directory
for ($i=0; $i<count($dir_subdirs); $i++) {
chmod($dir_subdirs[$i], $CFG->directorypermissions);
if (self::delete_dir_contents($dir_subdirs[$i]) == false) {
if (self::delete_dir_contents($dir_subdirs[$i], '', $progress) == false) {
return false;
} else {
if (remove_dir($dir_subdirs[$i]) == false) {
@ -125,9 +148,15 @@ abstract class backup_helper {
}
/**
* Delete all the temp dirs older than the time specified
* Delete all the temp dirs older than the time specified.
*
* If supplied, progress object should be ready to receive indeterminate
* progress reports.
*
* @param int $deletefrom Time to delete from
* @param core_backup_progress $progress Optional progress reporting object
*/
static public function delete_old_backup_dirs($deletefrom) {
static public function delete_old_backup_dirs($deletefrom, core_backup_progress $progress = null) {
global $CFG;
$status = true;
@ -140,7 +169,7 @@ abstract class backup_helper {
//If directory, recurse
if (is_dir($file_path)) {
// $file is really the backupid
$status = self::delete_backup_dir($file);
$status = self::delete_backup_dir($file, $progress);
//If file
} else {
unlink($file_path);