title: ZeroMQ reliability?
body: <p>I've been using ZeroMQ's request/response sockets for the purpose of exchanging messages between a web application and slave applications that were used for offloading processing. I've noticed that in a few cases, not all ZMQ messages sent were actually received by the other side. What's even weirded that this happens even with the <strong>IPC</strong> protocol, which, I thought, would be pretty reliable.</p>
  
  <p>What could be responsible for the sent message not being delivered, while not producing any errors?</p>
  
  <p><em>Here is an example of the client code:</em></p>
  
  <pre><code># ironic
  class ReliableClient(object):
      def _reconnect(self):
          if self.socket:
              self.socket.close()
              self.socket = None
  
          self.socket = self.context.socket(zmq.REQ)
          self.socket.connect(self.server_url)
  
          # Give the server 2 sec to respond
          self.socket.RCVTIMEO = 2000
          self.socket.SNDTIMEO = 2000
  
          self.socket.LINGER = 3
  
      def __init__(self, server_url=None, server_name=None):
          self.socket = None
          self.server_url = server_url
  
          if server_name is None:
              self.server_name = server_url
          else:
              self.server_name  = server_name
  
          self.lock = threading.Lock()
          self.context = zmq.Context()
  
          self._reconnect()
  
      def msg(self, msg):
          raw_out = dumps(msg)
  
          # send
          self.lock.acquire()
          try:
              self.socket.send(
                  raw_out,
                  copy=True
              )
          except zmq.ZMQError as ex:
              log.exception(ex, '%s: failed to send', self.server_name)
              self.lock.release()
              raise CommunicationError('failed to send')
  
          # receive
          try:
              raw_in = self.socket.recv()
          except zmq.ZMQError as ex:
              log.exception(ex, '%s: failed to receive', self.server_name)
              raise CommunicationError('failed to receive')
          finally:
              self.lock.release()
  
          msg_in = loads(raw_in)  
  
          return msg_in
  </code></pre>