Google App Engine のデータストアって、よく Timeout しますよね。(;^ω^)
本日、単純な Model.get() が Timeout したので、さすがに我慢できなくてリトライするように変更してみました。何かの参考になればとコードをアップしておきまーす♪
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import logging logging.basicConfig(level=logging.DEBUG) from google.appengine.api import datastore from google.appengine.api import datastore_errors _DB_RETRY_ATTEMPTS = 3 #リトライ回数 _DB_RETRY_INTERVAL = 0.2 #リトライの間隔基準。この場合 0.2s def autoretry(func): if func.__name__ == "_autoretry_wrapper": func = func._original_func def _autoretry_wrapper(*args, **kwargs): for num in range(1, _DB_RETRY_ATTEMPTS+1): try: return func(*args, **kwargs) except ( datastore_errors.Timeout, datastore_errors.TransactionFailedError ), e: sleeptime = num * _DB_RETRY_INTERVAL time.sleep(sleeptime) logging.warning("Datastore %s: retry %d/%d in %s seconds." % (e.__class__.__name__, num, _DB_RETRY_ATTEMPTS, sleeptime)) else: raise e _autoretry_wrapper._original_func = func return _autoretry_wrapper datastore.Get = autoretry(datastore.Get) datastore.Put = autoretry(datastore.Put) datastore.Delete = autoretry(datastore.Delete) |
※_original_func 関連のコードは別に無くても良いのですが、ローカルの開発環境ではコードの修正などに伴って問題が出ることがあるので、追加しています。たぶん本番環境では不要ですね。
なお、この変更にもし問題などが有りましたら、ご指摘頂けたら助かります!