Я начал использовать ZeroMQ на этой неделе, и при использовании шаблона Request-Response я не уверен, как заставить работника безопасно "повесить трубку" и закрыть его сокет, не отбрасывая сообщение и заставляя клиента, который отправил это сообщение, никогда не получайте ответа. Представьте себе работника, написанного на 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()
выкидывает все, что связано с сокетом.
Как рабочий может отсоединиться "безопасно" - есть ли способ сигнализировать "Я больше не хочу сообщений", затем (а) перебирать любые окончательные сообщения, которые были получены во время передачи сигнала, (b) сгенерировать их ответы, а затем (c) выполнить close()
с гарантией того, что сообщения не будут выброшены?
Изменить: Я предполагаю, что исходное состояние, которое я хотел бы ввести, является "полузакрытым" состоянием, в котором дальнейшие запросы не могут быть получены - и отправитель должен это знать, но где обратный путь по-прежнему открыт, поэтому я могу проверить свой входящий буфер на одно последнее сообщение и ответить на него, если в буфере есть один.
Изменить:. В ответ на хороший вопрос исправлено описание, чтобы количество ожидающих сообщений было множественным, так как при ответах было много подключений.