2012-07-30 python tornado web async subprocess
Пример асинхронного запуска процесса через subprocess из tornado.
Построчная выборка
import tornado.httpserver
import tornado.ioloop
import tornado.web
import subprocess
class MainHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
cmd = 'sleep 3; echo "1\n2\n3\n"; sleep 3; date; sleep 3'
def send(data):
if data:
self.write(data)
self.flush()
else:
self.finish()
self.subprocess(cmd, send)
def subprocess(self, cmd, callback):
ioloop = tornado.ioloop.IOLoop.instance()
PIPE = subprocess.PIPE
pipe = subprocess.Popen(cmd , shell=True, stdin=PIPE, stdout=PIPE,
stderr=subprocess.STDOUT, close_fds=True)
fd = pipe.stdout.fileno()
def recv(*args):
data = pipe.stdout.readline()
if data: callback(data)
elif pipe.poll() is not None:
ioloop.remove_handler(fd)
callback(None)
# read handler
ioloop.add_handler(fd, recv, ioloop.READ)
class TestHandler(tornado.web.RequestHandler):
def get(self):
self.write('Test')
application = tornado.web.Application([
(r"/", MainHandler),
(r"/test/", TestHandler),
], debug=True)
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()
import tornado.httpserver
import tornado.ioloop
import tornado.web
import subprocess
from tornado import gen
class MainHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@gen.engine
def get(self):
cmd = 'sleep 3; echo "1\n2\n3\n"; sleep 3; date; sleep 3'
result = yield gen.Task(self.subprocess, cmd)
self.finish(result)
def subprocess(self, cmd, callback):
ioloop = tornado.ioloop.IOLoop.instance()
PIPE = subprocess.PIPE
pipe = subprocess.Popen(cmd , shell=True, stdin=PIPE, stdout=PIPE,
stderr=subprocess.STDOUT, close_fds=True)
fd = pipe.stdout.fileno()
result = []
def recv(*args):
data = pipe.stdout.readline()
if data: result.append(data)
elif pipe.poll() is not None:
ioloop.remove_handler(fd)
callback(''.join(result))
ioloop.add_handler(fd, recv, ioloop.READ)
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()