小さなFlask
アプリを書いて、複数のログファイルをインターネット経由でブラウザにストリーミングしました。複数のログを複数のクライアントにストリーミングするFlaskアプリ
import json
import os
import re
import flask
from shelljob import proc
import eventlet
eventlet.sleep()
eventlet.monkey_patch()
app = flask.Flask(__name__)
@app.route('/stream/<string:case_name>/<string:wind_dir>')
def stream(case_name, wind_dir):
g = proc.Group()
foamrun = os.environ["FOAM_RUN"]
foamcase = os.path.join(foamrun, case_name, wind_dir)
log_file = os.path.join(foamcase, 'logs', 'run.log')
print log_file
p = g.run([ "tail", "-f", log_file ])
def read_process():
while g.is_pending():
lines = g.readlines()
for proc, line in lines:
# process line and create payload
yield "data:" + json.dumps(payload) + "\n\n"
return flask.Response(read_process(), mimetype='text/event-stream')
@app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET')
return response
if __name__ == "__main__":
foamrun = os.environ["FOAM_RUN"]
app.run(threaded=True, host='0.0.0.0', port=9001)
私は二つのリンクを開くと
gunicorn server:app -k eventlet -b 0.0.0.0:9001
コマンドでgunicorn
で、このアプリを実行します。
http://X.X.X.X:9001/stream/test01_base_Baseline/NW
http://X.X.X.X:9001/stream/test01_base_Baseline/N
を、私は奇妙な行動を持っています。 2つのストリームのうち1つは期待どおりに動作しますが、2つ目のストリームはハングするかバルクでストリーミングされます。たとえば、最初のページでは1秒間に1行ずつ、2ページ目には20秒ごとに15〜20行程度が表示されます。この振る舞いも一貫していません。ときには、最初のページがハングし、2番目が定期的に動作します。
私はウェブ開発にかなり新しいです。
EDIT
は、私は非常に簡単なバージョン
def read_process():
i = 1
while True:
payload = 'line' + str(i)
i += 1
yield "data:" + json.dumps(payload) + "\n\n"
sleep(1)
でread_process
を置き換えるために、このバージョンを試してみましたはないは同じ問題をhavetheと私は期待通りに動作しません。 2つのストリームは一緒に受信されます。
できるだけ早く 'eventlet.monkey_patch()'を実行してください - 最初の行にしてください。それでも問題が解決しない場合は、shelljobをスレッドプールにオフロードしてみてください。 'g = eventlet.tpool.Proxy(proc.Group())' – temoto
最初の行で 'eventlet.monkey_patch()'を動かす違いはありません。第二の選択肢は実際にそれを悪化させます。これらはともに立ち往生し、私はエラーを受け取ります: 'file" /usr/local/lib/python2.7/dist-packages/eventlet/queue.py "、118行目、switch、self.greenlet.switch(value)、エラー:別のスレッドに切り替えることができません。 ' – Rojj
スレッドプールの読み取り専用を試してください。 'lines = eventlet.tpool.execute(g.readlines)' – temoto