この質問は完全に App Engine 固有のものではありませんが、コンテキストを知るのに役立つ場合があります。App Engine には、ページをレンダリングし、さまざまなテーマやテーマ設定を介してスタイルを設定できる一種の「静的サイト ジェネレーター」があります。テーマは現在、App Engine ファイル システムに直接保存され、アプリケーションと共にアップロードされます。テーマは、いくつかのテンプレートと yaml 構成データで構成されます。
テーマの操作をカプセル化するために、Theme
クラスがあります。theme = Theme('sunshine')
たとえば、'sunshine' というテーマの構成データを読み込んで解析する Theme インスタンスを構築し、そのような呼び出しtheme.render_template('index.html')
でファイルシステム上の正しいファイルを自動的に読み込んでレンダリングできるようにします。
問題は、新しいリクエストが来て a をインスタンス化するたびに、テーマの (yaml) 構成データを読み込み、特に解析するのTheme
はコストがかかることです。したがって、データをプロセス/App Engine インスタンス内にキャッシュし、後で memcached 内にキャッシュしたいと考えています。
今まで、次のような非常に単純なキャッシュを使用してきました。
class Theme(object):
_theme_variables_cache = {}
def __init__(self, name):
self.name = name
if name not in Theme._theme_variables_cache:
Theme._theme_variables[name] = self.load_theme_variables()
...
(複数のリクエストがコンストラクターに同時にヒットした場合、構成が複数回読み取られる可能性があることは承知しています。ただし、問題が発生するとは思いません。)
しかし、その種のキャッシングはすぐに見苦しくなります。構成ファイルから読みたいものがいくつかありますが、すべての異なるテーマの「名前」も異なる基本構成を指しているため、すべてのキャッシュは辞書です。
私が持っていた最後のアイデアはTheme._cached_func(func)
、特定のテンプレートに対して関数の結果がまだキャッシュされていない場合にのみ func を実行するような関数を作成することでした (オブジェクトが別のテンプレートを表す場合、キャッシュされた値も異なる可能性があることに注意してください)。だから私はそれを次のように使うことができます: self.theme_variables = Theme._cached_func(self.load_theme_variables())
、しかし、私はまだPythonにかなり慣れていないので、ここで明らかな何かが欠けていると感じています.
クラス全体をキャッシュ ロジックで混乱させることなく、このような状況で機能する明確でクリーンな Python キャッシュ パターンはありますか? テンプレートごとにキャッシュが異なる必要があるため、デコレータなどを介して関数の結果をメモすることはできないと思います。プロセスの実行中に基になる構成データが変更されないため、「古い」キャッシュの処理は必要ありません。
アップデート
私はそのようにそれをやった:
class ThemeConfig(object):
__instances_cache = {}
@classmethod
def get_for(cls, theme_name):
return cls.__instances_cache.setdefault(
theme_name, ThemeConfig(theme_name))
def __init__(self, theme_name):
self.theme_name = theme_name
self._load_assets_urls() # those calls load yaml files
self._load_variables()
...
class Theme(object):
def __init__(self, theme_name):
self.theme_name = theme_name
self.config = ThemeConfig.get_for(theme_name)
...
ThemeConfig
そのため、テーマのファイルシステムから読み取られたすべての構成要素が保存され、ファクトリ メソッドThemeConfig.get_for
は同じテーマ名に対して同じ ThemeConfig インスタンスを常に渡します。私が持っている唯一のキャッシュ ロジックはファクトリ メソッドの 1 行であり、Theme
オブジェクトは以前と同じように一時的で共有されていないため、好きなように使用したり悪用したりできます。