Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement 'SomeAsyncWorker()' from Bottle Asynchronous Primer?

I have a bunch of long running scripts which do some number crunching and as they run write output to the console via print I want to invoke these scripts from a browser, and display the progress in the browser as they run. I'm currently playing with bottle and am working through this primer http://bottlepy.org/docs/dev/async.html# which is rather neat.

I'd like to try Event Callbacks http://bottlepy.org/docs/dev/async.html#event-callbacks as this seems to exactly match my problem, the script would run as an AsyncWorker (ideally managed by some message queue to limit the number running at any one instance) and periodically write back it's state. But I cannot figure out what SomeAsyncWorker() is - is it a tornado class or a gevent class I have to implement or something else?

@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
like image 282
David Waterworth Avatar asked Nov 10 '22 15:11

David Waterworth


1 Answers

I've found one way of doing this using gevent.queue here http://toastdriven.com/blog/2011/jul/31/gevent-long-polling-you/ which shouldn't be hard to adapt to work with bottle

# 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()
like image 132
David Waterworth Avatar answered Nov 15 '22 05:11

David Waterworth