Google App Engineでは、異なるWeb要求を異なるプロセスや異なる物理マシンに解決することがあります。つまり、さまざまなリクエスト間でグローバル状態を維持すること、つまりローカルののデータを実装することは少し難しくなります。
データが変更された場合、すべてのプロセス(キャッシュ一貫性の問題)でローカルキャッシュを無効にするように注意する必要があります。
さらに、GAEアプリケーションがthreadsafe
と定義されている場合、1つのプロセスで異なるスレッドで複数の要求を同時に処理できます。
私は可能な解決策をスケッチ:
- はを保つ
- グローバル辞書を使用して、処理中のデータのバージョンを追跡するグローバル辞書
- を使用してインプロセスデータを保持ゴールド小さなデータのバージョン
memcache
レコード(バージョンタグのみ、実際のデータではない)
- インプロセスのローカルデータが無効(無効)の場合、から取り出します適切な場合は、ゴールドバージョンタグをリセットして、すべてのマシン間でインプロセスデータを無効にします。ここ
コードである:
import threading
from uuid import uuid4
from google.appengine.api import memcache
_data = dict()
_versions = dict()
lock = threading.Lock()
TIME = 60 * 10 # 10 minutes
def get(key, value_provider):
"""
Gets a value from the in-process storage (cache).
If the value is not available in the in-process storage
or it is invalid (stale), then it is fetched by calling the 'value provider'.
"""
# Fast check, read-only step (no critical section).
if _is_valid(key):
return _data[key]
# Data is stale (invalid). Perform read+write step (critical section).
with lock:
# Check again in case another thread just left the critical section
# and brought the in-process data to a valid state.
if _is_valid(key):
return _data[key]
version = memcache.get(key)
# If memcache entry is not initialized
if not version:
version = uuid4()
memcache.set(key, version, time=TIME)
_data[key] = value_provider()
_versions[key] = version
return _data[key]
def _is_valid(key):
"""Whether the in-process data has the latest version (according to memcache entry)."""
memcache_version = memcache.get(key)
proc_version = _versions.get(key, None)
return memcache_version and memcache_version == proc_version
def invalidate(key):
"""Invalidates the in-process cache for all processes."""
memcache.set(key, uuid4(), time=TIME)
参照:
https://softwareengineering.stackexchange.com/a/222818
Understanding global object persistence in Python WSGI apps
Problem declaring global variable in python/GAE
Python Threads - Critical Section
https://en.wikipedia.org/wiki/Cache_coherence