如何从Bottle Asynchronous Primer实现'SomeAsyncWorker()'?

时间:2013-12-29 10:33:57

标签: python asynchronous bottle gevent

我有一堆长时间运行的脚本执行一些数字处理,并且当他们通过print运行写入输出到控制台时我想从浏览器调用这些脚本,并在浏览器运行时显示进度。我现在正在玩瓶子,正在使用这个引物http://bottlepy.org/docs/dev/async.html#,这是相当整洁的。

我想尝试事件回调http://bottlepy.org/docs/dev/async.html#event-callbacks,因为这似乎与我的问题完全匹配,脚本将作为AsyncWorker运行(理想情况下由某个消息队列管理,以限制在任何一个实例上运行的数量)并定期回写它的状态。但我无法弄清楚SomeAsyncWorker()是什么 - 它是龙卷风类还是我要实现的gevent类还是别的什么?

@route('/fetch')
def fetch():
    body = gevent.queue.Queue()
    worker = SomeAsyncWorker()
    worker.on_data(body.put)
    worker.on_finish(lambda: body.put(StopIteration))
    worker.start()
    return body

2 个答案:

答案 0 :(得分:1)

我找到了一种方法,使用gevent.queue http://toastdriven.com/blog/2011/jul/31/gevent-long-polling-you/这样做,这不应该很难适应瓶子

# wsgi_longpolling/better_responses.py
from gevent import monkey
monkey.patch_all()

import datetime
import time
from gevent import Greenlet
from gevent import pywsgi
from gevent import queue


def current_time(body):
    current = start = datetime.datetime.now()
    end = start + datetime.timedelta(seconds=60)

    while current < end:
        current = datetime.datetime.now()
        body.put('<div>%s</div>' % current.strftime("%Y-%m-%d %I:%M:%S"))
        time.sleep(1)

    body.put('</body></html>')
    body.put(StopIteration)


def handle(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    body = queue.Queue()
    body.put(' ' * 1000)
    body.put("<html><body><h1>Current Time:</h1>")
    g = Greenlet.spawn(current_time, body)
    return body


server = pywsgi.WSGIServer(('127.0.0.1', 1234), handle)
print "Serving on http://127.0.0.1:1234..."
server.serve_forever()

答案 1 :(得分:0)

(不完全是你问题的答案,但这是你可以采取的另一种方法。)

我拼凑了一个非常简单的multi-threaded WSGI server,非常适合瓶装。这是一个例子:

import bottle
import time
from mtbottle import MTServer

app = bottle.Bottle()

@app.route('/')
def foo():
    time.sleep(2)
    return 'hello, world!\n'

app.run(server=MTServer, host='0.0.0.0', port=8080, thread_count=3)

# app is nonblocking; it will handle up to 3 requests concurrently.
# A 4th concurrent request will block until one of the first 3 completed.

<强> https://github.com/RonRothman/mtwsgi

一个缺点是该端口上的所有端点都是异步的;相反,gevent方法(我认为)使您可以更好地控制哪些方法是异步的,哪些是同步的。

希望这有帮助!