2011-11-17 11 views
12

は、Google App Engineの中の私webapp2をアプリケーションに次のコードを考えてみましょアプリ。理解グローバルオブジェクトの永続性は、

私はすべてのリクエストが新しい地球環境だったPHPの世界から来ています。私がWebApp2のwsgi設定を使用しているため、Pythonは各リクエストで新しいプロセスを開始しません。私はCGIの設定を使用していた場合は、他の一方で、地球環境は...(ない場合は、私を修正してください)

上記と仮定が正しい... PHPのように、毎回再インスタンスでしょう

  1. 要求の存続期間中だけ永続化するグローバル変数が必要なシナリオは、どのように処理できますか?私はRequestHandlerクラスにインスタンス変数を置くことができますが、メッセージオブジェクトの格納などのためにグローバル変数を使用するユーティリティモジュールのようなものについてはどうでしょうか?
  2. すべての変数をリセットする、または環境の再インスタンス化を強制する技術はありますか?
  3. グローバル環境が無期限に持続するか、またはある時点でそれ自体がリセットされますか?
  4. このGAE固有のものも、wsgiグローバル持続性もどのサーバーシナリオでも同じですか?

EDIT:

ここで使用した試みだのThreadLocal:

count = 0 

mydata = threading.local() 
mydata.count = 0 

class MyHandler(webapp2.RequestHandler): 

    def get(self): 

     global count 
     count = count + 1 
     print count 

     mydata.count = mydata.count + 1 
     print mydata.count 

これらはまた、増分は全体の

+0

データストア以外でグローバルデータを保存しようとする具体的な理由はありますか?あなたがしようとしているものは、[シャードカウンター](http://code.google.com/appengine/articles/sharding_counters.html)で簡単に達成できるようです。 –

+0

@ Kevin-そのカウント変数は単なる例であり、実際のケースはまったく別のものです。アプリケーションドメイン内のグローバルスコープを理解しようとしています。 – Yarin

+0

関連[なぜPylonsはthreading.localの代わりにStackedObjectProxiesを使用しますか?](http://stackoverflow.com/q/1686768/95735) –

答えて

16

ご理解の方が正しいです。要求の持続期間中存続する変数が必要な場合は、それらをグローバルにする必要はありません。self.varとしてアクセスされるRequestHandlerクラスのインスタンス変数にしてください。リクエストごとに新しいRequestHandlerがインスタンス化されるため、変数は必要なだけ正確に保持されます。グローバル変数は、(リクエスト固有のスコープではなく)グローバルスコープを本当に必要としない限り、避けてください。

また、App Engineアプリは複数のサーバーで動作することに注意してください。グローバルは、同じサーバー内の要求にのみアクセスできます。

+3

複数のサーバーについての良い点 - ありがとう – Yarin

4

状況のあなたの分析が正しいことは、PythonのWebアプリケーションが要求しました長期実行プロセス。 Pythonインタプリタをスピンアップするのに時間がかかり、すべてのリクエストが完了するわけではありません。

"要求ごとに"異なるグローバル変数を作成することは完全に可能です。これは多くのフレームワークで行われ、人々はそれを好むようです。これを行う方法はサーバーによって異なります。ほとんどのサーバーでは「リクエストごとに1つのスレッド」を使用していますが、GAEも同様です。この場合、threadlocal variableを使用することができます。そのスレッドの要求の間にこの値があることを心配している場合は、要求の開始/終了にフックできる管理コードが必要になります。 WebApp2フレームワークが優れた方法を提供していない場合、WSGIミドルウェアはこれに適しています。

これはちょうどPythonであり、要求はそれ自身のスレッドで処理されます。そこからあなたが望むことをすることができます。 Pythonには、すべてのグローバル変数をリセットするだけのものは何もありません。通常、要求を処理するプロセスは毎回同じプロセスになるという保証はありません(GAEを中心に)。あなたがしていることを本当に知っている。

これを行うための優れたサポートを提供するフレームワークがたくさんあるので、WebApp2がそれ以外の場合は別の場所を探すことをお勧めします。 Pythonには多くのオプションがあり、その多くはGAE上で動作します。

+0

ありがとうございます。あなたは私の編集を見ていただけますか?私はthreading.local()を試みましたが、そのカウントは私のグローバルと同様に増加します。私はそれを正しく実装していますか? – Yarin

+0

あなたのリクエストは、同じスレッドに入っている可能性があります。ほとんどのWSGIサーバーはスレッドプールを使用して実装されているため、必ずしも要求ごとに*新しい*スレッドではありません。私は、GAEがWSGIアプリケーションをどのように動作させるかという内部的な仕組みに精通していませんが、これは私が期待しているものです。 –

2

あなたの最初の質問の場合は、webapp2.Request.registryの機能を考慮すると思います。要求の存続期間中に異なるモジュールが共有できるインスタンスを格納するのは、そのことです。

一方で、webapp2.WSGIApplication.registryも有用です。この場合、インスタンスは要求の間に存続し、アプリケーションの存続期間中にアプリケーションが必要とするものに対して共有(および再利用)することができ、グローバルスコープでのインスタンスの作成を回避できます。