-
Type: Bug
-
Resolution: Done
-
Priority: Minor - P4
-
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)