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