В моих приложениях 0MQ я обычно делаю это, чтобы справиться с тайм-аутом:
import zmq
ctx = zmq.Context()
s = ctx.socket(zmq.DEALER)
s.connect("tcp://localhost:5555")
# send PING request
v = <some unique value>
s.send_multipart(["PING", v])
if s.poll(timeout * 1000) & zmq.POLLIN:
msg = s.recv_multipart()
...
Однако, если сервер не работает и через несколько минут выходит в сеть, 0MQ автоматически переподключится и отправит сообщение. Однако, если я добавлю команду send PING в значение oop (раз в секунду) и сервер не будет работать, то, как только сервер вернется в оперативный режим, я получу следующий вызов recv_multipart()
- старые сообщения, которые остались во внутренней очереди 0MQ, когда сервер был в автономном режиме. Потому что меня не волнуют старые сообщения, хотя я мог бы сделать это:
s = ctx.socket(zmq.DEALER)
s.connect("tcp://localhost:5555")
while True:
# send PING request
v = <some unique value>
s.send_multipart(["PING", v])
if s.poll(timeout * 1000) & zmq.POLLIN:
msg = s.recv_multipart()
...
else:
s.close()
s = ctx.socket(zmq.DEALER)
s.connect("tcp://localhost:5555")
time.sleep(1)
Но это плохая идея, через некоторое время ctx.socket
поднимает ZMQError: Too many open files
. Установка опции сокета ZMQ_LINGER
на 0, кажется, здесь помогает, но теперь мне не нравится эта стратегия, она мне кажется неправильной.
Так что в идеале я хотел бы отбросить ранее отправленное сообщение, если прочитано тайм-аут случается. Это а) возможно и б) хорошая идея вообще? Я не уверен, что это было бы правильно, хотя, возможно, 0MQ может физически отправить сообщение, но сервер падает, прежде чем он может что-либо отправить обратно, поэтому удаление будет невозможно, потому что не будет ничего, чтобы отбросить, было бы?
Итак, мой вопрос: что мне делать в этой ситуации? Возможно, я смотрю на эту проблему под неправильным углом?