# Добавление длительных задач

Plesk SDK API позволяет выполнять длительные задачи и отображать ход их выполнения в интерфейсе Plesk UI. Чтобы запустить длительную задачу и в дальнейшем отслеживать ее выполнение, создайте класс для длительной задачи, который расширяет pm_LongTask_Task и определите для него метод run(). Можно также настроить поведение длительной задачи путем перезаписи методов onStart(), onError() и onDone(), которые по умолчанию не выполняют никаких действий.

Во время написания метода run() вам может понадобиться также получить определенную информацию о задаче с помощью геттеров (getInstanceId(), getParam(), getParams(), getStatus() и getProgress()) и обновить информацию о задаче с помощью сеттеров (setParam(), setParams() и updateProgress()). Любые скалярные типы данных и массивы принимаются в качестве параметров задачи. Объекты не могут быть параметрами задачи.

Выполнение длительных задач осуществляется в интерфейсе Plesk UI по умолчанию. Метод statusMessage() отвечает за отображение сообщения, которое появляется в строке состояния задачи. Состояние длительной задачи может быть либо отслеживаемым, либо нет (по умолчанию оно не может отслеживаться). Если вы хотите сделать состояние задачи отслеживаемым, для свойства $trackProgress надо выставить значение «true», и тогда состояние задачи можно будет обновить с помощью метода updateProgress() во время выполнения задачи. Если задачу вообще не надо отображать в интерфейсе Plesk, для свойства $hidden надо выставить значение «true».

Метод getId() определяет идентификатор задачи. Он может быть получен из имени класса задачи путем удаления префикса & имени модуля (например, Modules_Example_Task_Create => task_create; PleskExtExampleTaskCreate => taskcreate; TaskCreate => taskcreate). Вы можете переопределять его так, как вам надо, и использовать для получения очереди задач.

Как только длительная задача создана, необходимо зарегистрировать ее в Plesk. Класс Modules_<Extension name>_LongTasks должен быть получен из pm_Hook_LongTasks и помещен в папку `plib/hooks/`.

Наконец, можно использовать класс pm_LongTask_Manager для запуска длительных задач, их отмены и получения очереди задач. Имейте в виду, что задача может быть выполнена:

- В контексте домена – в этом случае она будет видимой только в контексте указанного домена или, если ни один домен не активен (например, в режиме Service Provider).
- Вне контекста – в этом случае она будет видимой, только если ни один домен не активен (например, в режиме Service Provider).

Все задачи расширения будут удалены при удалении расширения.

## Примеры

Пример задачи с отслеживаемым состоянием (PRODUCT_ROOT_D . /admin/plib/modules/example/library/Task/Create.php):

    class Modules_Example_Task_Create extends pm_LongTask_Task
    {
        public $trackProgress = true;

        public function run()
        {
            sleep(2);
            $this->updateProgress(30);
            sleep(2);
            $this->updateProgress(60);
            sleep(2);
            $this->updateProgress(90);
            sleep(2);
        }

        public function statusMessage()
        {
            switch ($this->getStatus()) {
                case static::STATUS_RUNNING:
                    return pm_Locale::lmsg('running');
                case static::STATUS_DONE:
                    return pm_Locale::lmsg('done', ['id' => $this->getId()]);
            }
            return '';
        }

        public function onStart()
        {
            $this->setParam('onStart', 1);
        }

        public function onDone()
        {
            $this->setParam('onDone', 1);
        }
    }

Пример регистрации задачи (PRODUCT_ROOT_D . /admin/plib/modules/example/hooks/LongTasks.php):

    class Modules_Example_LongTasks extends pm_Hook_LongTasks
    {
        public function getLongTasks()
        {
            return [new Modules_Example_Task_Create()];
        }
    }

Пример управления задачей:

    $taskManager = new pm_LongTask_Manager();

    $task1 = new Modules_Example_Task_Create();
    $task1->setParam('counter', 15); //set task param
    $taskManager->start($task1); // start task

    $task2 = new Modules_Example_Task_Create();
    $task2 = $taskManager->start($task2, new pm_Domain(1)); // start task in context of domain #1

    $tasks = $taskManager->getTasks(['task_create']); // get tasks with no context, $task1
    $tasks = $taskManager->getTasks(['task_create'], [new pm_Domain(1)]); // get tasks with domain #1 context, $task1, $task2

    $taskManager->cancel($task1); // cancel $task1 execution and delete it
    $taskManager->cancelAllTasks(); // cancel all extension tasks execution and delete them