1

メールサーバーに対する認証を処理するPASプラグインを実装しています。実際には、DBMailのみが実装されています。

enumerateUsersPASプラグインの関数はリクエストごとに何度も呼び出され、プラグインはすべての(後続の)リクエストに対してSQL接続を開閉する必要があることに気付きました。もちろん、これは非常に高価です。

enumerateUsers接続自体は、複数の異なるメールサーバーを処理し、登録済みサーバーを表すラッパーオブジェクトへの呼び出しを委任することができるploneツールで処理されます。

私の質問は、列挙を繰り返すための一時的なローカルストレージを提供し、後続のSQL接続を回避するために、どのような種類のキャッシュ(OOBTree、Session?)を使用する必要があるかということです。

もう1つのアイデアは、最初のログイン時に行われるユーザー作成プロセスに接続することで、外部ユーザーが発行し、ユーザーを完全に「ローカライズ」することでした。

3番目のアイデアは、可能であれば、必要なデータを特定のメンバーに格納することでした。

ここでのベストプラクティスは何でしょうか?

4

1 に答える 1

4

確かに、クエリ結果をキャッシュします。結果をキャッシュする期間と、長期間保存する場合は、そのキャッシュを無効にする方法または変更を確認する方法を決定する必要があります。

これらの決定には、保存されるデータの種類とバックエンドの API に完全に依存するため、ベスト プラクティスはありません。たとえば、ある種の鮮度クエリをサポートしている場合は、すべてを永久に保存し、バックエンドをポーリングして、キャッシュを更新する必要があるかどうかを確認します。

単純なリクエスト キャッシュから始めることができます。リクエストごとに 1 回クエリを実行し、リクエスト オブジェクトに保存します。リクエスト オブジェクトがクリーンアップされると、キャッシュはリクエストの最後に自動的に無効になります。次のリクエストは白紙の状態になります。

バックエンド ユーザーがほとんど変更されない場合は、ローカル キャッシュに情報をより長くキャッシュできます。プラグインで揮発性属性を使用します。で始まる属性_v_は、永続化機構によって無視されます。したがって、_v_揮発性属性に格納されているものはすべてスレッドローカルであり、プロセスの存続期間中のみ存在し、サーバーを再起動するとこれらは自動的にクリアされます。

少なくとも、_v_揮発性属性を使用してバックエンド SQL 接続を保存する必要があります。そうすれば、リクエスト間で開いたままにして再利用できます。次のような方法がうまくいくでしょう:

def _connection(self):
    # Return a backend connection
    if getattr(self, '_v_connection', None) is None:
        # Create connection here
        self._v_connection = yourdatabaseconnection
    return self._v_connection

プラグインで永続的な属性を使用して、キャッシュを保存することもできます。このキャッシュは ZODB にコミットされ、再起動後も保持されます。次に、コンテンツを無効にする方法を実際に検討する必要があります。タイムスタンプを保存し、古くなったときにデータを削除するなど。

キャッシュのデータ構造は、アプリケーションのニーズに完全に依存します。情報を永続化しない場合は、辞書 (ユーザー名 -> 情報) で十分です。永続キャッシュはOOBTree、異なるスレッド間の競合の可能性を減らし、大量のデータ セットに関してはより効率的であるため、ディクショナリの代わりに を使用することでメリットが得られます。

何をするにしても、セッションを使用する必要はありません。セッションは競合しやすく、拡張性が低く、いずれにせよ、この種のキャッシュを保存する場所ではありません。

于 2012-09-20T09:06:08.247 に答える