Um wiederholte Berechnungen zu vermeiden, können bei zeitaufwändigen Abfragen verteilte Sperrdienste verwendet werden.
Es wird jeweils nur ein Vorgang ausgeführt, und ähnliche Vorgänge warten darauf, erneut versucht zu werden Der folgende Code (fetch_with_dist_lock) definiert einen Fetcher und einen Updater.
Wenn der Fetcher die Daten nicht abrufen kann, wird der Updater zum Aktualisieren verwendet Es gibt auch Situationen, in denen wir nur aktualisieren möchten. Es gibt mehrere Updater für bestimmte Daten, aber der Update-Vorgang ist nicht atomar. Dann führen wir ihn über update_with_dist_lock aus
def fetch_with_dist_lock(mc_store, mutex_key, fetcher, updater, lock_time=3*60*1000, sleep_time=100, retry_times=3): i = 0 while i < retry_times: i += 1 need_update, results = fetcher() if need_update: if(mc_store.add(mutex_key, lock_time)): try: updater() continue finally: #release the distribute mutex anyway mc_store.delete(mutex_key) else: time.sleep((sleep_time*1.0)/1000) continue return results #too much tries, but failed still. return None def f_wrapper(f, *args, **kwargs): def _(): return f(*args, **kwargs) return _ def update_with_dist_lock(mc_store, mutex_key, updater, lock_time=60*1000, sleep_time=100, retry_times=5): i = 0 while i < retry_times: i += 1 if (mc_store.add(mutex_key, lock_time)): try: updater() return True finally: mc_store.delete(mutex_key) else: time.sleep((sleep_time*1.0)/1000) continue return False