2

Django を使用して App Engine で Python アプリケーションを実行しています。さらに、私は というセッション管理ライブラリを使用していgae-sessionsます。threadsafeが に設定されている場合は"no"問題ありませんが、 が にthreadsafe設定されて"yes"いる場合、セッションが失われる問題が時々見られます。

私が見ている問題は、トレッドが有効になっている場合、GAE-Sessions ミドルウェアで複数のリクエストが時折インターリーブされることです。

gae-sessionsライブラリ内には、変数_tlsである という変数がありthreading.local()ます。ユーザーが Web サイトに対して http 要求を行うと、呼び出された関数process_request()が最初に実行され、続いて現在のページの一連のカスタム html が生成され、次に呼び出された関数process_response()が実行されます。process_requestとの間の状態はprocess_response_tls「スレッドセーフ」変数に記憶されます。_tls値を出力することで、変数の一意性を確認でき_tlsます (例: "<thread._local object at 0xfc2e8de0>")。

私が時折目にするのは、GAE-Sessions ミドルウェアのシングル スレッドのように見えるものです (thread_local オブジェクトのメモリ位置が同じであるという事実からシングル スレッドであると推測され、データがあるリクエストから別のリクエストのデータを上書きしているように見えます)、複数の http リクエストがインターリーブされています。User1 と User2 が同時にリクエストを行うと、次の実行順序が確認されました。

User1 -> `process_request` is executed on thread A
User2 -> `process_request` is executed on thread A
User2 -> `process_response` is executed on thread A
User1 -> `process_response` is executed on thread A

上記のシナリオでは、User2 セッションがいくつかの内部変数を踏みにじり、User1 のセッションが失われます。

だから、私の質問は次のとおりです: 1) App-Engine/Django/Python で予想されるミドルウェアの異なる要求のインターリーブですか? (または、私は完全に混乱しており、ここで何か他のことが起こっています) 2) このインターリーブはどのレベルで発生していますか (App-Engine/Django/Python)?

私はこの動作を見て非常に驚いているので、ここで何が起こっているのか/何が起こっているのかを理解したいと思っています.

4

1 に答える 1

2

次のリンクは、何が起こっているのかを理解するのに役立つことがわかりました。

私がすべてを正しく理解していると仮定すると、上記が起こった理由は次のとおりです。

1)Djangoが実行されている場合、Djangoミドルウェアを含む親(共通)スレッドでほとんどの基本機能が実行されます。

2)個々のリクエストは、親スレッドと対話できる子スレッドで実行されます。

上記の結果、リクエスト(子スレッド)は実際にミドルウェア内でインターリーブできます。これは仕様によるものです(Djangoとミドルウェアのコピーを1つだけ実行すると、メモリが節約され、効率が向上します)。[スレッド化と子/親プロセスがどのように相互作用するかについての簡単な説明については、この回答でリンクした最初の記事を参照してください]

-に関してGAE-Sessions、私たちが調べていたスレッドは、ミドルウェアが入った。

GAE-Sessions親(Django + Middlware)スレッド内で子スレッドがインターリーブされる可能性があるため、状態データをミドルウェアに格納していました。これは、さまざまな要求によって上書きされる可能性があります。私が適用した修正はGAE-Sessions、ミドルウェア内ではなく、リクエストオブジェクトにすべての状態データを保存することでした。

修正:以前は、応答ハンドラー関数への書き込み可能な参照がDjangoSessionMiddlwareオブジェクトにself.response_handlers-として格納されていましたが、これをリクエストオブジェクトに移動しましたrequest.response_handlers_tlsまた、変数を削除し、それに含まれるデータをrequestオブジェクトに移動しました。

于 2013-01-07T11:56:43.963 に答える