簡體   English   中英

httpretty.enable()之后MongoClient連接失敗

[英]MongoClient ConnectionFailure after httpretty.enable()

每當啟用HTTPretty時,我就無法與PyMongo建立連接。 我知道HTTPretty會更改核心套接字模塊; 有沒有辦法解決?

代碼示例:



    import pymongo
    import httpretty
    import time

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

引發異常:



    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

我在Windows 8.1中使用Python 3.3。

誰能解釋這種現象以及如何解決? 謝謝!

看起來正在引發的異常與HTTPretty的猴子修補套接字有關,每當我們在非HTTP請求中調用sendall時,該套接字都會在其自己的套接字上調用settimeout(0) (請參閱real_sendall )。 這會將套接字置於非阻塞模式。 real_sendall之后,套接字上的超時永遠不會重置,因此后續對recv調用會因WSAEWOULDBLOCK (errno 10035)而失敗。 這可能是HTTPretty中的錯誤。

一種解決方法是在real_sendall之后重置套接字上的超時。 這可以通過在HTTPretty中猴子修補fakesocket.socket來完成:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM