我正在编写一个简单的基于浏览器的前端,它应该能够启动后台任务,然后从中获取进度。我希望浏览器收到一个响应,说明任务是否成功启动,然后轮询以确定任务何时完成。但是,后台任务的存在似乎会阻止立即发送 XMLHttpRequest 响应,因此我无法报告启动该进程的成功。考虑以下(简化的)代码:
import SocketServer
import SimpleHTTPServer
import multiprocessing
import time
class MyProc(multiprocessing.Process):
def run(self):
print 'Starting long process..'
for i in range(100): time.sleep(1)
print 'Done long process'
class Page(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
print >>self.wfile, "<html><body><a href='/run'>Run</a></body></html>"
if self.path == '/run':
self.proc = MyProc()
print 'Starting..'
self.proc.start()
print 'After start.'
print >>self.wfile, "Process started."
httpd = SocketServer.TCPServer(('', 8000), Page)
httpd.serve_forever()
当我运行这个并浏览到http://本地主机:8000 http://localhost:8000,我得到一个名为“运行”的按钮。当我点击它时,终端显示:
Starting..
After start.
然而浏览器视图并没有改变......事实上光标在旋转。仅当我在终端中按 Ctrl-C 中断程序时,浏览器才会更新消息Process started.
消息After start
显然正在打印。因此我可以假设do_GET
启动进程后返回。然而,直到我中断长时间运行的进程后,浏览器才会得到响应。我必须得出结论,两者之间存在某种阻碍do_GET
以及正在发送的响应,位于内部SimpleHTTPServer
.
我也尝试过使用线程和 subprocess.Popen 但遇到了类似的问题。有任何想法吗?
除了上面史蒂夫和我的评论之外,这里还有一个适合我的解决方案。
确定内容长度的方法有点难看。如果您不指定,尽管显示了内容,浏览器仍可能显示旋转的光标。关闭self.wfile
相反也可以工作。
from cStringIO import StringIO
class Page(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
out = StringIO()
self.send_response(200)
self.send_header("Content-type", "text/html")
if self.path == '/':
out.write("<html><body><a href='/run'>Run</a></body></html>\n")
elif self.path == '/run':
self.proc = MyProc()
print 'Starting..'
self.proc.start()
print 'After start.'
out.write("<html><body><h1>Process started</h1></body></html>\n")
text = out.getvalue()
self.send_header("Content-Length", str(len(text)))
self.end_headers()
self.wfile.write(text)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)