2015-04-12 42 views
0

下面的代码在某个URL(/ new ...)上执行并将变量分配给会话cookie,该cookie用于构建显示。这个例子使用subprocess.Popen调用一个命令。Python瓶,处理Popen轮询/等待/沟通,无需停止多线程Python

问题是,下面调用的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,包括瓶0.10.1

回答

1

首先,你应该使用像芹菜,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('/') 

现在,它不会挡住你的视线! :)