• Модуль: disk
  • Путь к файлу: ~/bitrix/modules/disk/lib/volume/cleaner.php
  • Класс: BitrixDiskVolumeCleaner
  • Вызов: Cleaner::runTask
protected function runTask(): bool
{
	$task = $this->instanceTask();
	$indicator = $task->getIndicator();
	if (!$indicator instanceof VolumeIVolumeIndicator)
	{
		return true;
	}

	if ($task->getStatus() != VolumeTask::TASK_STATUS_RUNNING)
	{
		$task->setStatus(VolumeTask::TASK_STATUS_RUNNING);
	}

	// subTask to run
	$subTask = '';
	if (VolumeTask::isRunningMode($task->getStatusSubTask(VolumeTask::DROP_TRASHCAN)))
	{
		$subTask = VolumeTask::DROP_TRASHCAN;
	}
	elseif (VolumeTask::isRunningMode($task->getStatusSubTask(VolumeTask::EMPTY_FOLDER)))
	{
		$subTask = VolumeTask::EMPTY_FOLDER;
	}
	elseif (VolumeTask::isRunningMode($task->getStatusSubTask(VolumeTask::DROP_FOLDER)))
	{
		$subTask = VolumeTask::DROP_FOLDER;
	}
	elseif (VolumeTask::isRunningMode($task->getStatusSubTask(VolumeTask::DROP_UNNECESSARY_VERSION)))
	{
		$subTask = VolumeTask::DROP_UNNECESSARY_VERSION;
	}

	$repeatMeasure = function () use ($indicator, $task)
	{
		// reset offset
		$task->setLastFileId(0);
		$task->fixState();

		$retry = 1;
		while ($retry <= 3)
		{
			try
			{
				// check final result repeat measure
				self::repeatMeasure($indicator);
			}
			catch (MainDBSqlQueryException $exception)
			{
				if (mb_stripos($exception->getMessage(), 'deadlock found when trying to get lock; try restarting transaction') !== false)
				{
					// retrying in a few seconds
					sleep(5);
					$retry ++;
					continue;
				}

				throw $exception;
			}
			break;
		}

		// reload task
		$task->loadTaskById($indicator->getFilterId(), $task->getOwnerId());
	};

	// run subTask
	$taskDone = false;
	switch ($subTask)
	{
		case VolumeTask::DROP_TRASHCAN:
		{
			if ($task->getStatusSubTask($subTask) != VolumeTask::TASK_STATUS_RUNNING)
			{
				$task->setStatusSubTask($subTask, VolumeTask::TASK_STATUS_RUNNING);
			}

			if($this->deleteTrashcanByFilter($indicator))
			{
				$repeatMeasure();
				$taskDone = $task->hasTaskFinished($subTask);
			}
			elseif ($task->hasFatalError())
			{
				$taskDone = true;
			}

			break;
		}

		case VolumeTask::EMPTY_FOLDER:
		case VolumeTask::DROP_FOLDER:
		{
			if ($task->getStatusSubTask($subTask) != VolumeTask::TASK_STATUS_RUNNING)
			{
				$task->setStatusSubTask($subTask, VolumeTask::TASK_STATUS_RUNNING);
			}

			$folderId = $task->getParam('FOLDER_ID');
			$folder = DiskFolder::getById($folderId);
			if ($folder instanceof DiskFolder)
			{
				if ($this->deleteFolder($folder, ($subTask === VolumeTask::EMPTY_FOLDER)))
				{
					$repeatMeasure();
					$taskDone = $task->hasTaskFinished($subTask);
				}
				elseif ($task->hasFatalError())
				{
					$taskDone = true;
				}
			}
			else
			{
				$task->setLastError('Can not found folder #'.$folderId);
				$task->raiseFatalError();
				$taskDone = true;
			}

			break;
		}

		case VolumeTask::DROP_UNNECESSARY_VERSION:
		{
			if ($task->getStatusSubTask($subTask) != VolumeTask::TASK_STATUS_RUNNING)
			{
				$task->setStatusSubTask($subTask, VolumeTask::TASK_STATUS_RUNNING);
			}

			if($this->deleteUnnecessaryVersionByFilter($indicator))
			{
				$repeatMeasure();
				$taskDone = $task->hasTaskFinished($subTask);
			}
			elseif ($task->hasFatalError())
			{
				$taskDone = true;
			}

			break;
		}

		default:
		{
			$taskDone = true;
		}
	}

	if($taskDone)
	{
		// finish
		$task->setStatusSubTask($subTask, VolumeTask::TASK_STATUS_DONE);
		$task->setStatus(VolumeTask::TASK_STATUS_DONE);
	}

	// Fix task state
	$task->fixState();


	return $taskDone;
}