1

一部のタスク(電子メール送信など)が終了しない前にフラスコをどのようにレンダリングできますか?

問題

私たちの場合、ユーザーが登録情報をサーバーに送信している間、サーバーは最初に認証メールを送信し、次に成功ページをレンダリングします。ただし、メールの送信が完了するまでには常に 3 ~ 5 秒かかります。つまり、登録情報を送信してから応答を得るまでに少なくとも 3 秒かかります。

私たちが行ったこと

1.信号

このことを行うために、シグナルを送信してメール送信関数をトリガーしてみました。

if approved:
    # ...

    send_activation_signal.send(email)

    login_user(u)
    return redirect(url_for('register_success'))

結果

register_success ページがレンダリングされるまでに少なくとも 3 秒かかることを除けば、すべて問題ありません。

2. スレッドをフォークする

スレッドを fork してメール送信を終了する

t = threading.Thread(target = send_activation, args = (email, username, email_confirm_code, ))
t.start()

結果

しかし、リクエストコンテキストが正しく処理されていないようです。

> Exception in thread Thread-2: Traceback (most recent call last):  
> File
> "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py",
> line 552, in __bootstrap_inner
>     self.run()   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py",
> line 505, in run
>     self.__target(*self.__args, **self.__kwargs)   File "/Users/arthasshih/flask/happyvs/main_app/views/user.py", line 267, in
> send_activation
>     app.logger.debug("sending #############")   File "/Users/arthasshih/virtual_evns/normal/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/local.py",
> line 336, in __getattr__
>     return getattr(self._get_current_object(), name)   File "/Users/arthasshih/virtual_evns/normal/lib/python2.7/site-packages/Werkzeug-0.8.3-py2.7.egg/werkzeug/local.py",
> line 295, in _get_current_object
>     return self.__local()   File "/Users/arthasshih/virtual_evns/normal/lib/python2.7/site-packages/Flask-0.8-py2.7.egg/flask/globals.py",
> line 19, in _lookup_object
>     raise RuntimeError('working outside of request context') RuntimeError: working outside of request context
4

1 に答える 1

4

フラスコでメール送信を設定するときにもこの問題に直面しましたが、問題はフラスコではありません。メール送信タスクを終了する前にフラスコを返す場合、このプロセスは非同期で実行する必要がありますが、ここでは同期的に実行されているため、待機する必要があります。

ソリューションはCelery: Distributed Task Queueを使用しています。このテキストはホームページからのものです:

これは、分散メッセージ パッシングに基づく非同期タスク キュー/ジョブ キューです。タスクは、非同期 (バックグラウンド) または同期 (準備が整うまで待機) で実行できます。

Flask-Celeryと呼ばれる Flask 拡張機能もあります。これにより、セロリをフラスコに簡単に統合できます。

セロリの非同期タスクキューにメール送信タスクを追加し、ページをレンダリングするだけです。タスクが失敗した場合、セロリがエラーログを生成することを確認する必要があります。そうしないと、メールが送信されたかどうかに関係なく生成されます。

于 2012-06-17T17:58:27.890 に答える