【发布时间】:2011-08-23 19:42:58
【问题描述】:
所以我正在尝试在类似于 Buildbot 的 web 应用程序的 stdio 流中工作。有谁知道 Buildbot 如何处理 stdio?它正在流式传输(看起来如此),而这正是我对这个程序所需要的。
有人知道怎么做吗?
任何帮助将不胜感激。
顺便说一下,我正在使用 Python 和 Django
【问题讨论】:
所以我正在尝试在类似于 Buildbot 的 web 应用程序的 stdio 流中工作。有谁知道 Buildbot 如何处理 stdio?它正在流式传输(看起来如此),而这正是我对这个程序所需要的。
有人知道怎么做吗?
任何帮助将不胜感激。
顺便说一下,我正在使用 Python 和 Django
【问题讨论】:
Buildbot 使用Twisted,其编程风格与 Django 截然不同。
我会说你必须在 Twisted 中编写一个服务来完成你所追求的。从 Django 与它通信,让它做你需要的流媒体部分。
(在 Django 中,与大多数 Web 应用程序一样,每个请求都有一个线程/调用阻塞 db/io 调用。在 Twisted 中,您将异步函数调用推迟到库中,并且一旦 io完成了。一开始感觉有点奇怪,但实际上相当不错,尤其是对于不仅仅是网络服务器的应用程序。)
【讨论】:
Django 允许您从视图中返回迭代器。您可以返回一个迭代器,它以增量方式读取流并将其返回给 django。 request-response/#passing-iterators ex. snippet
这是最简单的解决方案
from django.core.servers.basehttp import FileWrapper
from subprocess import Popen, PIPE
from django.contrib.auth.decorators import user_passes_test
@user_passes_test(lambda u: u.is_superuser) #SECURE THIS SHIT
def stdout_cmd(request, command):
#buffsize=1 reads a char at a time
process = Popen(command, shell=True, buffsize='1', stdout=PIPE)
# FileWrapper creates an iterator class for stdout
wrapper = FileWrapper(process.stdout)
# text/plain causes monospaced output in browser
return HttpResponse(wrapper, content_type='text/plain')
只要你可以创建一个类似文件的对象,你就可以将它包装在 FileWrapper 中。 请注意,如果您的 shell 的输出是零星的,您将需要创建自己的迭代器,一次读取一行,例如
wrapper = (line for line in process.stdout) # brackets create an iterator object
注意:如果您有太多并发的长轮询页面加载,这将消耗工作线程并阻止人们连接到您的服务器。考虑使用 gevent/greenlets。适用于高流量环境。
【讨论】: