Gearman & PHP: правильный способ для работника отослать отказ - PullRequest
10 голосов
/ 28 февраля 2011

Документы 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;
}

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

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

1 Ответ

8 голосов
/ 16 марта 2011

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

Я использую 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 ().

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

...