简体   繁体   中英

MongoClient ConnectionFailure after httpretty.enable()

Whenever I enable HTTPretty, I'm unable to make a connection with PyMongo. I know that HTTPretty alters the core socket module; is there any way around this?

Code Example:



    import pymongo
    import httpretty
    import time

    httpretty.enable()
    try:
        client = pymongo.MongoClient()
    except pymongo.errors.AutoReconnect:
        print("AutoReconnect")
        time.sleep(2)

Raises exception:



    Traceback (most recent call last):
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 363, in __init__
        self._ensure_connected(True)
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 924, in _ensure_connected
        self.__ensure_member()
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 797, in __ensure_member
        member, nodes = self.__find_node()
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 888, in __find_node
        raise AutoReconnect(', '.join(errors))
    pymongo.errors.AutoReconnect: [WinError 10035] A non-blocking socket operation could not be completed immediately

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "tmp.py", line 7, in 
        client = pymongo.MongoClient()
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 366, in __init__
        raise ConnectionFailure(str(e))
    pymongo.errors.ConnectionFailure: [WinError 10035] A non-blocking socket operation could not be completed immediately

I am on Windows 8.1 using Python 3.3.

Can anyone explain this behavior and how to resolve it? Thanks!

It looks like the Exception being raised has to do with HTTPretty's monkey-patched socket, which calls settimeout(0) on its own socket whenever we call sendall on something that isn't an HTTP request (see real_sendall ). This puts the socket in non-blocking mode. The timeout on the socket is never reset after real_sendall , so subsequent calls to recv fail with WSAEWOULDBLOCK (errno 10035). This might be a bug in HTTPretty.

One workaround for this is to reset the timeout on the socket after real_sendall . This can be accomplished by monkey-patching fakesocket.socket in HTTPretty:

from httpretty.core import fakesock

class MySocket(fakesock.socket):
    def real_sendall(self, data, *args, **kw):
        super(MySocket, self).real_sendall(data, *args, **kw)
        # Restore non-zero timeout
        self.truesock.settimeout(self.timeout)

fakesock.socket = MySocket

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM