Uploaded image for project: 'Python Driver'
  1. Python Driver
  2. PYTHON-968

InterruptedError not handled

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Minor - P4 Minor - P4
    • 3.2
    • Affects Version/s: 3.0.3
    • Component/s: None
    • None
    • Environment:
      Debian Jessie, Python 3.4

      Hello, I am setting signal handlers in my Python program:

              signal.signal(signal.SIGTERM, handle_stop) 
              signal.signal(signal.SIGINT,  handle_stop)
              # handle_stop is some trivial function
      

      When I press Ctrl-C while pymongo is receiving data an InterruptedException is raised:

      Traceback (most recent call last):
        File "/usr/local/lib/python3.4/dist-packages/pymongo/pool.py", line 214, in receive_message
          return receive_message(self.sock, operation, request_id)
        File "/usr/local/lib/python3.4/dist-packages/pymongo/network.py", line 60, in receive_message
          header = _receive_data_on_socket(sock, 16)
        File "/usr/local/lib/python3.4/dist-packages/pymongo/network.py", line 76, in _receive_data_on_socket
          chunk = sock.recv(length)
      InterruptedError: [Errno 4] Interrupted system call
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "/usr/lib/python3.4/multiprocessing/process.py", line 254, in _bootstrap
          self.run()
        File "/usr/lib/python3.4/multiprocessing/process.py", line 93, in run
          self._target(*self._args, **self._kwargs)
        File "/home/messa/code/lh/lh-insights-backend/lh_insights_indexer/manager.py", line 99, in <lambda>
          self.target = lambda: self.indexer.run(poll=self.poll)
        File "/home/messa/code/lh/lh-insights-backend/lh_insights_indexer/batch_enumerator/batch_enumerator.py", line 39, in run
          limit=self._batch_count))
        File "/usr/local/lib/python3.4/dist-packages/pymongo/cursor.py", line 983, in next
          if len(self.__data) or self._refresh():
        File "/usr/local/lib/python3.4/dist-packages/pymongo/cursor.py", line 908, in _refresh
          self.__read_preference))
        File "/usr/local/lib/python3.4/dist-packages/pymongo/cursor.py", line 813, in __send_message
          **kwargs)
        File "/usr/local/lib/python3.4/dist-packages/pymongo/mongo_client.py", line 744, in _send_message_with_response
          exhaust)
        File "/usr/local/lib/python3.4/dist-packages/pymongo/mongo_client.py", line 755, in _reset_on_error
          return func(*args, **kwargs)
        File "/usr/local/lib/python3.4/dist-packages/pymongo/server.py", line 88, in send_message_with_response
          response_data = sock_info.receive_message(1, request_id)
        File "/usr/local/lib/python3.4/dist-packages/pymongo/pool.py", line 216, in receive_message
          self._raise_connection_failure(error)
        File "/usr/local/lib/python3.4/dist-packages/pymongo/pool.py", line 314, in _raise_connection_failure
          _raise_connection_failure(self.address, error)
        File "/usr/local/lib/python3.4/dist-packages/pymongo/pool.py", line 58, in _raise_connection_failure
          raise AutoReconnect(msg)
      pymongo.errors.AutoReconnect: 127.0.0.1:27304: [Errno 4] Interrupted system call
      

      I think only a small change is necessary to solve this - in pymongo/network.py, replace

      
      def _receive_data_on_socket(sock, length):
          msg = b""
          while length:
              chunk = sock.recv(length)
              if chunk == b"":
                  raise AutoReconnect("connection closed")
      
              length -= len(chunk)
              msg += chunk
      
          return msg
      

      with

      
      def _receive_data_on_socket(sock, length):
          msg = b""
          while length:
              try:
                  chunk = sock.recv(length)
              except InterruptedError:
                  continue
              if chunk == b"":
                  raise AutoReconnect("connection closed")
      
              length -= len(chunk)
              msg += chunk
      
          return msg
      

      (At least for Python 3.4, I'm not sure for Python 2.x)

            Assignee:
            anna.herlihy@mongodb.com Anna Herlihy (Inactive)
            Reporter:
            messa Petr Messner
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: