以下代码在某个URL(/ new ...)上执行,并将变量分配给会话cookie,用于构建显示。此示例使用subprocess.Popen。
调用命令问题是下面调用的Popen命令通常需要3分钟 - 而subprocess.communicate等待输出 - 在此期间所有其他Flask调用(例如另一个用户连接)都将暂停。我有一些注释行与我尝试过的其他事情没有成功 - 一个使用线程模块,另一个使用subprocess.poll。
from app import app
from flask import render_template, redirect, session
from subprocess import Popen, PIPE
import threading
@app.route('/new/<number>')
def new_session(number):
get_list(number)
#t = threading.Thread(target=get_list, args=(number))
#t.start()
#t.join()
return redirect('/')
def get_list(number):
#1 Call JAR Get String
command = 'java -jar fetch.jar' + str(number)
print "Executing " + command
stream=Popen(command, shell=False, stdout=PIPE)
#while stream.poll() is None:
# print "stream.poll = " + str(stream.poll())
# time.sleep(1)
stdout,stderr = stream.communicate()
#do some item splits and some processing, left out for brevity
session['data'] = stdout.split("\r\n")
return
正确处理这种情况的“更好的做法”是什么?
作为参考,此代码在win32上的Python 2.7.8中运行,包括Flask 0.10.1
答案 0 :(得分:2)
首先,您应该使用像Celery,RabbitMQ或Redis这样的工作队列(这里是helpful hint)。
然后,定义get_list
函数变为:
@celery.task
def get_list(number):
command = 'java -jar fetch.jar {}'.format(number)
print "Executing " + command
stream = Popen(command, shell=False, stdout=PIPE)
stdout, stderr = stream.communicate()
return stdout.split('\r\n')
在你看来,你等待结果:
@app.route('/new/<number>')
def new_session(number):
result = get_list.delay(number)
session['data'] = result.wait()
return redirect('/')
现在,它不会阻止您的观点! :)