Ale*_*ade 6 python generator multiprocessing gevent bottle
我有一个 Bottle 应用程序,它使用子进程来完成大部分请求工作。对于返回单个响应的路由,我会执行如下操作。
@route('/index')
def index():
worker = getWorker()
return worker.doStuff()
Run Code Online (Sandbox Code Playgroud)
我的路线之一需要是数据流。我想不出让工作人员返回响应流的聪明方法。下面的例子和我想做的类似,只是没有工人。
@route('/stream')
def stream():
yield 'START'
sleep(3)
yield 'MIDDLE'
sleep(5)
yield 'END'
Run Code Online (Sandbox Code Playgroud)
我希望能够做类似下面的事情。由于我无法产生/返回生成器,因此不可能以这种方式进行。
@route('/stream')
def stream():
worker = getWorker()
yield worker.doStuff()
class worker:
# Remember, this is run in a subprocess in real life.
def doStuff():
yield 'START'
sleep(3)
yield 'MIDDLE'
sleep(5)
yield 'END'
Run Code Online (Sandbox Code Playgroud)
这是一个大型项目,我做事的方式没有太大的灵活性。我知道有时最简单的答案是“你的设计是错误的”。但在这种情况下,我有一些超出我控制范围的约束(路由必须是数据流,工作必须由子进程完成)。
编辑 我也不能有 doStuff() 块。我希望能够创建类似 gevent 队列的东西,我返回并拥有工作进程。现在的问题是,我似乎不能同时使用 gevent.queue 和 Process。
@route('/stream')
def index():
body = gevent.queue.Queue()
worker = multiprocessing.Process(target=do_stuff, args=body)
worker.start()
return body()
def do_stuff(body):
while True:
gevent.sleep(5)
body.put("data")
Run Code Online (Sandbox Code Playgroud)
经过大量研究和实验,我确定 gevent 队列不能以这种方式与 Python 多处理一起使用。除了以这种方式做事之外,还可以使用像 redis 这样的东西来允许进程和 gevent greenlet 进行通信。
@route('/stream')
def index():
worker = multiprocessing.Process(target=do_stuff)
worker.start()
yield redis_server.lpop()
def do_stuff(body):
while True:
gevent.sleep(5)
redis_server.lpush("data")
Run Code Online (Sandbox Code Playgroud)