2016-09-01 7 views
0

異なるRequestHandlerインスタンスのグローバルdefaultdictにアクセスしても安全ですか?例えば。そうでない場合異なったtornado.RequestHandlerインスタンスからグローバル/共有defaultdictへのアクセス/更新

GlobalMap = defaultdict(list) 

class Event(tornado.web.RequestHandler): 
    def get(self, unit): 
     # This is where the access/modify might happen 
     # The list.append() is just an arbitrary example 
     GlobalMap[unit].append(datetime.utcnow()) 
     self.write(b'') 

、異なるRequestHandlerインスタンス間でキー付きデータの検索/保存を行うための適切な方法は何ですか?

答えて

1

はい、これは問題ありません。トルネードコードは通常、メインスレッドで実行されます。このようなPythonデータ構造にアクセスするコード。

しかし、実稼働環境にTornadoアプリケーションをデプロイする場合、複数のマシン上で実行される複数のTornadoプロセスが必要なので、共有データベースサーバーにデータを入れてプロセス間で共有したいと考えています。

+0

私は「トルネードは数万のオープンな接続に拡張できる」と考えました。これを実現するには、竜巻サーバーの複数のインスタンスを実行する必要があります。 tornado.pyを複数回起動すると、複数の異なるソケットアドレスにバインドする必要はありませんか?次に、着信トラフィックを複数の異なる内部ソケットにルーティングする方法はありますか?元の質問の範囲のすべての側に、しかしあなたの第2段落。 –

+1

トルネードは何千もの接続を処理できます。複数のインスタンスを使用して作業を分散することができます。トラフィックは、gunicron、nginx、またはその他のロードバランサを使用するインスタンス間で負荷分散されます。これはエンタープライズレベルのアプリケーションの典型ですが、あなたが個人的に使用するためにTornadoを使用している場合は、複数のインスタンスについてあまりストレスを感じません。 –

1

非同期/スレッド/マルチプロセスのアプリケーションでは、グローバル変数にアクセスするのは安全です。のように、共有状態を持つことは決して良い考えではありません。しかし、ほとんどの場合、グローバルなdictの値にアクセスすることは、特にシングルスレッドの非同期アプリケーションではかなり安全です。

一方、最終的にすべてのRequestHandlerクラスを1つのモジュールに格納するのは難しくなります。辞書をデータストアとして使用することは効果的にスケールアウトできません。 A. Jesse Jiryu Davisが彼の答えに含意しているのは、GlobalMapにあるデータは、共有できるように何らかのデータベースに格納する必要があるということです。 MongoDBやRedisのような従来のdictオブジェクトのように大きく感じるデータベースソリューションが数多くあります。

更新

あなたApplicationオブジェクトを作成するときにも、追加のパラメータを渡すことができます。

GlobalMap = defaultdict(list) 

class Event(tornado.web.RequestHandler): 
    def initialize(self, shared_dict): 
     self.shared_dict = shared_dict 

app = Application([ 
    #... 
    (r"/", Event, dict(shared_dict=GlobalMap)) 
]) 

Application docsURLSpec docsを見てみましょう:だからあなたのメインモジュールでは、あなたのような何かを行うことができます。私はこれを以前に思い出さないためにちょっとばかげていると感じます。これはTornadoアプリケーション間のアクセシビリティを処理しますが、他のモジュールではそれほど多くはありません。その場合、外部データベースが必要になります。

+0

このアプリケーションは実際には意図的に小さい/単純/単一ファイルです。私がそれを1つのファイルよりも大きくすると、私は何か間違ったことをした。 :)しかし、それだけでなく、モジュール間の境界を扱うために、 "global"データをtornado.applicationインスタンスの属性として入れることができますか?そして、リクエストは単に 'self.application._myGlobalMap ['foo']'にアクセスしますか? –

+0

'' tornado.application''にクラス変数を追加できなかった理由はわかりませんが、簡単な方法はアプリケーションの作成時に渡すことだと思います。私の更新された答えを見てください。あなたが見ることができるように、私はトルネードにもかなり新しいです; P –

関連する問題