Я начал использовать ZeroMQ на этой неделе, и при использовании шаблона «запрос-ответ» я не уверен, как заставить работника безопасно «повесить» и закрыть свой сокет, возможно, не отбрасывая сообщение и не вызывая клиента, который отправил это сообщение никогда не получить ответ. Представьте себе работника, написанного на Python, который выглядит примерно так:
import zmq
c = zmq.Context()
s = c.socket(zmq.REP)
s.connect('tcp://127.0.0.1:9999')
while i in range(8):
s.recv()
s.send('reply')
s.close()
Я проводил эксперименты и обнаружил, что клиент с 127.0.0.1:9999
типа сокета zmq.REQ
, который делает запрос с честной очередью, просто может потерпеть неудачу, если алгоритм честной очереди выберет вышеуказанного работника сразу после работник выполнил последний send()
, но перед тем, как запустить следующий close()
метод. В этом случае кажется, что запрос получен и буферизован стеком ØMQ в рабочем процессе и что запрос теряется, когда close()
выбрасывает все, что связано с сокетом.
Как рабочий может отсоединить «безопасно» - есть ли какой-либо способ подать сигнал «Я больше не хочу сообщений», затем (а) перебрать все окончательные сообщения, которые поступили во время передачи сигнала, (б) сгенерировать их ответы, а затем (с) выполнить close()
с гарантией того, что никакие сообщения не будут выброшены?
Редактировать: Я полагаю, что необработанное состояние, в которое я хотел бы войти, является "полузакрытым" состоянием, когда дальнейшие запросы не могут быть получены - и отправитель узнает об этом - но где возврат путь по-прежнему открыт, так что я могу проверить свой входящий буфер на одно последнее поступившее сообщение и ответить на него, если в буфере присутствует одно из них.
Редактировать: В ответ на хороший вопрос исправил описание, сделав количество ожидающих сообщений множественным, так как может быть много соединений, ожидающих ответов.