12

(標準の Flask デバッグ Web サーバーのように) 1 つの要求をブロックして別の要求に応答するのではなく、eventletを使用して同時要求に即座に応答する最小限の Flask アプリケーションをセットアップしようとしています。

前提条件:

pip install Flask
pip install eventlet

これまでにインターネットで見つけたものによる私の理解から、次のように機能するはずです。

# activate eventlet
import eventlet
eventlet.monkey_patch()

from flask import Flask

import datetime
from time import sleep

# create a new Flask application
app = Flask(__name__)

# a short running task that returns immediately
@app.route('/shortTask')
def short_running_task():
  start = datetime.datetime.now()
  return 'Started at {0}, returned at {1}'.format(start, datetime.datetime.now())

# a long running tasks that returns after 30s
@app.route('/longTask')
def long_running_task():
  start = datetime.datetime.now()
  sleep(30)
  return 'Started at {0}, returned at {1}'.format(start, datetime.datetime.now())

# run the webserver
if __name__ == '__main__':
    app.run(debug=True)

このファイルを実行http://localhost:5000/longTaskしてから、Web ブラウザのタブで開いhttp://localhost:5000/shortTaskて、.. ただし、これを標準の Werkzeug サーバーで実行する場合と同様に、2 番目のタブは最初のタブが 30 秒後に終了した直後にのみ戻ります。

ここで何が問題なのですか?ところで、予想される同時ユーザー数が少ない (最大 5) ことを考えると、これは一般的に Flask の「本番対応 Web サーバー」と呼ばれるものでしょうか?

ちなみに、Flask-socketio ライブラリを使用して Web サーバーを実行すると、ドキュメントによると、イベントレットがインストールされている場合は自動的に選択され、期待どおりに動作します。

Flask-socketio を使用した完全な例:

# activate eventlet
import eventlet
eventlet.monkey_patch()

from flask import Flask
from flask_socketio import SocketIO

import datetime
from time import sleep

# create a new Flask application
app = Flask(__name__)

# activate Flask-socketio
socketio = SocketIO(app)

# a short running task that returns immediately
@app.route('/shortTask')
def short_running_task():
  start = datetime.datetime.now()
  return 'Started at {0}, returned at {1}'.format(start, datetime.datetime.now())

# a long running tasks that returns after 30s
@app.route('/longTask')
def long_running_task():
  start = datetime.datetime.now()
  sleep(30)
  return 'Started at {0}, returned at {1}'.format(start, datetime.datetime.now())

# run the webserver with socketio
if __name__ == '__main__':
    socketio.run(app, debug=True)
4

2 に答える 2

2
import eventlet
eventlet.monkey_patch()

あなたのコードを魔法のように、要求を非同期に処理できるマルチスレッドの獣に変えることはありません (それでも、かなり魔法のようで素晴らしいものです)。

この例でわかるように、イベントレット wsgi の実装wsgiを使用してサーバーを起動する必要があります。

標準的なソリューションが必要な場合は、nginx と uwsgi を使用してフラスコ アプリケーションを起動する方法をご覧ください。また、完全なマルチスレッド wsgi ハンドラーを作成する手間を活用するプロジェクトSpawningにも興味があるかもしれません。

于 2016-01-11T13:25:06.500 に答える