2012-03-29 5 views
36

Flaskアプリケーション内のPythonで新しいスレッドを開始しようとしています。私は、要求によって引き起こされるバックグラウンド作業をしていますが、要求に応答するために作業が完了するのを待つ必要はありません。フラスコがサブスレッドを開始するときに「リクエストコンテキスト外で動作しています」

このサブ脅威のフラスコ要求は、入ってきた要求に設定できますか?理由は、私たちのDB(mongoDBの前のmongoengine)への問い合わせに対する私たちのACLは、要求に応じて(フラスコのリクエストオブジェクトから取得した)リクエストのユーザに依存しています。サブスレッドでは使用できません。

ご意見をいただければ幸いです。

ここで私はどのように扱っているのか疑似コードですが、動作しません。

@app.route('/my_endpoint', methods=['POST']) 
def my_endpoint_handler(): 
    #do tracking in sub-thread so we don't hold up the page 
    def handle_sub_view(req): 
     from flask import request 
     request = req 
     # Do Expensive work 
    thread.start_new_thread(handle_sub_view, (request)) 
    return "Thanks" 
+1

を渡すことができますか? –

+0

フラスコはいつでもリクエストにアクセスできるため、ドキュメントベースのクラスにはリクエストからユーザを取得するクエリセットマネージャがあります。私がやっている仕事はクエリーセットマネージャーよりもはるかに高いレベルなので、ユーザーだけで使うことはできません – MattoTodd

+0

リクエストはスレッド/コンテキストローカルですので、利用できません。 。私はまだ依頼オブジェクトの依存関係をリファクタリングするべきだと考えています。 –

答えて

44

はそうあなたがcontext localsへのアクセスを持ってtest_request_contextであなたのスレッドコードをラップ:

@app.route('/my_endpoint', methods=['POST']) 
def my_endpoint_handler(): 
    #do tracking in sub-thread so we don't hold up the page 
    def handle_sub_view(req): 
     with app.test_request_context(): 
      from flask import request 
      request = req 
      # Do Expensive work 
    thread.start_new_thread(handle_sub_view, (request)) 
    return "Thanks" 

編集:それはスレッドが元の要求と異なるコンテキストを持っていることを指摘する価値があります。スレッドを作成する前に、ユーザーIDなどの興味深い要求データを抽出する必要があります。その後、IDを使用してサブスレッド内の(異なる)ユーザーオブジェクトを取得できます。あなたはbefore_requestフックは、あなたが装飾された機能の中current_app.preprocess_request()を呼び出す必要があります実行したい場合はhttp://flask.pocoo.org/docs/api/#flask.copy_current_request_context

+2

また、これを抽象化してみることもできます。http://celeryproject.org/メールを送信するなどの操作をブロックするために使用します。良いことは、mongoDBをバックエンドとして使用できることです。スタックに何かを追加する必要はありません。 – Ross

27

は、バージョン0.10以降これを行うためのサポート方法があります。

4

あなたは目的の情報をコピーして、あなただけの理由だけではなく、サブスレッドにユーザーを渡すし、ユーザーが必要な場合は、それを

@app.route('/my_endpoint', methods=['POST']) 
def my_endpoint_handler(): 
    #do tracking in sub-thread so we don't hold up the page 
    def handle_sub_view(data): 
     # Use the data in subprocess 
    data = request.get_json() # copy the data 
    thread.start_new_thread(handle_sub_view, data) 
    return "Thanks" 
+0

それは便利ではありません。私はアプリに関するすべてのデータをコピーする必要があります。 – jamlee

関連する問題