Поэтому я использую beanstalk_console (https://github.com/ptrofimov/beanstalk_console) для наблюдения за моей очередью beanstalkd, и иногда я получаю 1 или 2 работы, застрявшие в погребенном состоянии. Это связано с тем, что у меня настроен рабочий код, когда я сразу закапываю работу после ее зарезервирования и удаляю ее, если все идет хорошо (иначе она останется похороненной). Я также использую Supervisord для управления несколькими работниками очереди. Пример быстрого кода ниже:
$pheanstalk = new Pheanstalk();
$pheanstalk->watch('tube');
while ($job = $pheanstalk->reserve()) {
$pheanstalk->bury($job);
$success = false;
// Process job here. Set $success to true if no errors were encountered
if ($success) {
$pheanstalk->delete($job);
}
}
Теперь к моей проблеме: я заметил, что, если я использую beanstalk_console, чтобы переместить мои скрытые задания обратно в назначенные им каналы, будут случайные моменты времени, когда все мои доступные работники будут резервировать одну и ту же работу в одно и то же время (что интересно, все с другой работой id), что приводит к дублированию работы. Все они также будут похоронены в одно и то же время, хотя beanstalk_console будет отображать только последнюю скрытую работу, поэтому я не уверен, что происходит. Если я добавлю что-то вроде sleep(1)
незадолго до того, как я похороню свою работу, только один работник резервирует работу, и я не получаю дублирующую работу. Это почти то же самое, что сразу же похоронить работу после того, как резервирование поставит ее обратно в очередь. Что-то не так с моим кодом? Или что-то странное с тем, как beanstalk_console возвращает задания обратно?
Когда кажется, что предыдущие проблемы, как это происходит, обычно потому, что связь между рабочим скриптом & beanstalkd падает, и поэтому задание возвращается в очередь, которую можно забрать в другом месте.
Также обязательно перехватывайте все соответствующие исключения и проверяйте возвраты, чтобы вы знали, что происходит.
Итак, я вновь обратился к этой проблеме и посмотрю, почему она возникает сейчас. Beanstalk Console использует цикл do while для поиска оставшихся рабочих мест и будет выходить из него только после того, как возникнет исключительная ситуация из-за того, что не будет найдено больше скрытых заданий.
https://github.com/ptrofimov/beanstalk_console/blob/1.7.7/lib/include.php#L765
К сожалению, похоже, что цикл может перехватывать задания, которые я немедленно хороню (как в моем примере кода) задолго до того, как выдается исключение, что может привести к тому, что одно и то же задание обрабатывается более одного раза. Также не имеет значения, есть ли у меня 1 или более работников, ожидающих работы. Больше работников означает больше обработки дубликатов.