Skip to content

Instantly share code, notes, and snippets.

@edigiacomo
Last active August 29, 2015 14:09
Show Gist options
  • Select an option

  • Save edigiacomo/182f83cda76a95843ff0 to your computer and use it in GitHub Desktop.

Select an option

Save edigiacomo/182f83cda76a95843ff0 to your computer and use it in GitHub Desktop.
Un processo viene lanciato alla connessione del client, il quale ne riceve lo stdout e può interromperlo chiudendo la connessione.
# encoding: utf-8
import tornado.httpserver
import tornado.iostream
import tornado.ioloop
import tornado.web
import tornado.process
import tornado.concurrent
import concurrent.futures
import subprocess
class AsyncHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
self.proc = tornado.process.Subprocess(
["bash", "-c", "while true; do openssl rand 256|od ; done"],
stdout=tornado.process.Subprocess.STREAM,
)
self.set_proc_stdout_read()
self.proc.set_exit_callback(self.on_proc_exit)
self.proc.stdout.set_close_callback(self.on_proc_stdout_close)
def on_finish(self):
print("Request terminated")
def set_proc_stdout_read(self):
self.proc.stdout.read_until_close(
self.on_proc_stdout_read_end,
streaming_callback=self.on_proc_stdout_stream_read,
)
def on_proc_stdout_read_end(self, data):
print("Terminated stdout read")
def on_proc_stdout_stream_read(self, data):
print("{} bytes read".format(len(data)))
self.write(data)
self.flush()
def on_proc_stdout_close(self):
print("Stdout closed")
def on_proc_exit(self, r):
print("Process {} exited with status: {}".format(self.proc.pid, r))
self.finish()
def on_connection_close(self, *args, **kwargs):
print("Client has closed the connection")
self.proc.stdout.close()
self.proc.proc.terminate()
class PoolAsyncHandler(tornado.web.RequestHandler):
bufsize = 1024
executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
@tornado.web.asynchronous
def get(self):
self.future = self.run_process()
@tornado.concurrent.run_on_executor
def run_process(self):
self.proc = subprocess.Popen(
["bash", "-c", "while true; do openssl rand 256|od ; done"],
stdout=subprocess.PIPE,
)
while True:
b = self.proc.stdout.read(self.bufsize)
if not b:
break
self.write(b)
self.flush()
self.finish()
def on_connection_close(self, *args, **kwargs):
self.proc.terminate()
self.future.cancel()
def run_app():
application = tornado.web.Application([
(r"/async", AsyncHandler),
(r"/pool", PoolAsyncHandler),
])
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(5000)
tornado.ioloop.IOLoop.instance().start()
if __name__ == '__main__':
run_app()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment