2012-03-23 138 views

回答

5

我不認爲有一種優雅的方式。 Pymongo具有AutoReconnect異常,如果先前建立的連接丟失,將拋出異常。您應該捕獲此異常並重試將導致連接重新建立的操作。

處理我發現AutoReconnects是一個相對簡單的辦法就是DB操作在不同的方法分離,並用類似下面的裝飾包裹其中:

from pymongo.errors import AutoReconnect 

def autoreconnect_retry(fn, retries=3): 
    def db_op_wrapper(*args, **kwargs): 
     tries = 0 

     while tries < retries: 
      try: 
       return fn(*args, **kwargs) 

      except AutoReconnect: 
       tries += 1 

     raise Exception("No luck even after %d retries" % retries) 

用法:

@autoreconnect_retry 
def insert_foo_record(foo): 
    # Perform db operation 
    pass 

@autoreconnect_retry(20) 
def get_foo_record(id): 
    # Perform db operation 
    pass 
0

在pymongo2.2連接url中可以選擇添加附加參數:

mongodb://<user>:<password>@<host>:<port>/<db>?options 

支持的選項之一是connectTimeoutMS即

mongodb://<user>:<password>@<host>:<port>/<db>?connectTimeoutMS=300 

,以連接超時擴展到pymongo爲300ms

更高版本具有相同的選項

0

的相似的變化有了給你會有像錯誤的解決方案'NoneType'對象不可調用,或* autoreconnect_retry()至少需要1個參數(1給定)*。在這裏,你已經測試和運行的代碼來裝點基於kristaps其執行pymongo操作所有的方法,回答:

from pymongo.errors import AutoReconnect 

def autoreconnect_retry(retries=3): 
""" 
Decorator for connection retrial in mongoDB 
""" 
def autoreconnect_retry_decorator(fn): 
    def db_op_wrapper(*args, **kwargs): 
     tries = 0 

     while tries < retries: 
      try: 
       return fn(*args, **kwargs) 

      except AutoReconnect: 
       tries += 1 

     raise Exception("No luck even after %d retries" % retries) 

    return db_op_wrapper 
return autoreconnect_retry_decorator 

然後你可以裝飾用參數的方法如前所述:

@autoreconnect_retry 
def some_pymongo_operation(): 
    pass 

@autoreconnect_retry(20) 
def some_pymongo_operation(): 
    pass 
+0

可能只是返回你db_op_wrapper,它會工作。不需要添加另一個裝飾器。您也有很多縮進錯誤。 – rick112358 2017-04-30 14:08:18

+0

@ rick112358如果你想傳遞裝飾器參數中的重試次數,你需要第二個包裝器。如果你不想這個配置是,你可以跳過外部裝飾器。 Stackoverflow代碼示例不會像現在這樣工作,也不會被編譯,它只是代碼準則。用這個策略工作多年,沒有任何問題,那就說Mongodb 2.6分支 – danigosa 2017-05-01 10:53:03

+0

我說你可以在不使用第二個裝飾器的情況下實現同樣的效果,如kristaps的答案所示。克里斯塔普斯的回答只是缺少一個回報聲明。讓我告訴你發生了什麼,你複製了粘貼的kristaps答案,看到了一條錯誤消息,並且在調試時創建了這個混亂而不理解實際問題是什麼。 – rick112358 2017-05-02 04:29:32