Как пометить сообщение как "в процессе", чтобы другие работники не работали над ним

Я пытаюсь использовать очередь извлечения для создания очереди задач обработки изображений, которая может занять больше времени, чем ограничение acktimeout, равное 10 минутам. Я использую API.js node.js, и мне интересно, как можно было бы, чтобы работник получил сообщение из очереди извлечения, пометил его как выполняемый, чтобы другие работники не пытались его захватить, выполнить его работу и подтвердить сообщение после обработка завершена. Эта обработка может занять до часа на одного работника. Если возникает исключение, я хотел бы удалить статус "в процессе" и позволить другим работникам забрать это сообщение и попытаться обработать его.

Я надеялся, что в pubsub было что-то, что позволило бы мне сделать это. Моя альтернатива состоит в том, чтобы перед обработкой сохранить сущность (inProgressMessage) с идентификатором сообщения, идентификатором подтверждения, состоянием = ожидание, timestamp=now() в хранилище данных, чтобы работник сразу же возвращал ackid после получения сообщения (это позволит другим работникам, чтобы попытаться другие сообщения), то работник может работать над длительной задачей. В случае успеха пометьте статус объекта как завершенный, если произошел сбой непостоянным образом, повторно запустите задачу в pubsub, если произошел сбой постоянным способом, который не позволяет запросить запрос, у меня может быть cron, который проверяет хранилище данных на наличие отложенных задач старше нескольких часов и пусть они будут удалены или помещены в очередь.

Моя альтернатива чувствует, что я повторно внедряю многое из того, с чем паб-саб должен помочь.

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

2 ответа

Решение

Чтобы обработать сообщение дольше, чем установленный крайний срок подтверждения, вам нужно использовать modifyAckDeadline. Вы можете продлить срок столько раз, сколько вам нужно, до 10 минут на звонок. Ваш рабочий процесс будет следующим:

  1. Вытащите сообщение.
  2. Начните обрабатывать сообщение.
  3. Пока вы не закончили с сообщением, если вы близки к 10-минутному крайнему сроку подтверждения, вызовите modifyAckDeadline, чтобы продлить крайний срок.
  4. Как только закончите обработку сообщения, подтвердите его.

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

При создании темы (только) вы можете настроить время подтверждения до 10 минут ( https://cloud.google.com/pubsub/subscriber). Как только сообщение было извлечено из очереди, никакой другой работник (того же абонента) не сможет принять его для обработки, если не был достигнут ack ttl, а затем сообщение автоматически возвращается в очередь.

Поскольку вам требуется более длительный период, вам придется что-то реализовывать самостоятельно или искать другое решение для очередей. Я думаю, что предложенный вами дизайн довольно прост в реализации и не является ре-реализацией того, что делает pubsub.

Другие вопросы по тегам