Gearman & PHP: правильный способ для работника отправить отказ

Документы PHP немного нечеткие на этом, поэтому я прошу об этом здесь. С учетом этого рабочего кода:

<?php
$gmworker= new GearmanWorker();
$gmworker->addServer();
$gmworker->addFunction("doSomething", "doSomethingFunc");
while($gmworker->work());

function doSomethingFunc()
{
    try {
        $value = doSomethingElse($job->workload());
    } catch (Exception $e) {
        // Need to notify the client of the error
    }

    return $value;
}

Каким образом можно уведомить клиента о любой ошибке, которая произошла? Вернуть false? Использовать GearmanJob:: sendFail()? Если это последнее, мне нужно вернуться из моего doSomethingFunc() после вызова sendFail()? Должно ли возвращаемое значение быть возвращенным функцией sendFail()?

Клиент использует GearmanClient:: returnCode() для проверки сбоев. Кроме того, просто использование "return $value", похоже, работает, но нужно ли вместо этого использовать GearmanJob:: sendData() или GearmanJob:: sendComplete()?

Ответ 1

Это может быть не лучший способ сделать это, но это метод, который я использовал в прошлом, и он хорошо сработал у меня.

Я использую sendException(), а затем sendFail() в рабочем документе, чтобы вернуть сбой задания. Часть исключений является необязательной, но я использую ее, чтобы клиент мог ошибочно и точно знать, почему это не удалось. После sendFail я ничего не верну. В качестве примера это метод, который рабочий регистрирует как обратный вызов для выполнения работы:

public function doJob(GearmanJob $job)
{
    $this->_gearmanJob = $job;


    try{
        //This method does the actual work
        $this->_doJob($job->functionName());
    }
    catch (Exception $e) {
        $job->sendException($e->getMessage());
        $job->sendFail();
    }
}

После того, как sendFail() ничего не возвращает, в противном случае вы можете получить странные результаты, такие как сервер заданий, считая, что работа закончилась нормально.

Что касается возвращаемых данных, я использую sendData(), если я возвращаю данные в виде кусков (например, потоковое транскодированное видео или любые "большие" данные, в которых я не хочу перемещаться по одной большой капли) с различными интервалами во время моя работа с sendComplete() в конце. В противном случае, если я хочу только вернуть свои данные за один проход в конце задания, я использую sendComplete().

Надеюсь, что это поможет.