2014-06-20 1 views
1

Chaque fois que j'active HTTPretty, je ne peux pas établir de connexion avec PyMongo. Je sais que HTTPretty modifie le module de socket de base; Y a-t-il un moyen de contourner cela?MongoClient ConnectionFailure après httpretty.enable()

Exemple de code:



    import pymongo 
    import httpretty 
    import time 

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

exception soulève:



    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 

Je suis sous Windows 8.1 en utilisant Python 3.3. Quelqu'un peut-il expliquer ce comportement et comment le résoudre?

Merci!

Répondre

2

Il semble que l'exception soulevée a à voir avec la prise de singe patché de HTTPretty , qui appelle settimeout(0) sur sa propre prise chaque fois que nous appelons sendall sur quelque chose qui n'est pas une requête HTTP (voir real_sendall). Ce place le socket en mode non bloquant. Le délai d'attente sur le socket n'est jamais réinitialisé après real_sendall, donc les appels suivants à recv échouent avec WSAEWOULDBLOCK (erreur 10035). Cela pourrait être un bug dans HTTPretty. Une solution de contournement pour cela est de réinitialiser le délai d'attente sur le socket après real_sendall. Ceci peut être accompli par le singe-patcher fakesocket.socket dans 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 
+0

Je me suis rendu compte que le problème était dans le rapiéçage de singe, et ma solution était d'essayer de mon mieux pour juste activer() et désactiver() httpretty autour de mes appels mongo. C'est beaucoup mieux, merci. – bmsauer

+0

En outre, la dernière ligne doit être fakesock.socket = MySocket. – bmsauer

+0

Ah oui, merci pour la correction. Mise à jour de ma réponse pour utiliser le bon nom de classe. – llovett

Questions connexes