Skip to content

Instantly share code, notes, and snippets.

@cuadue
Created May 17, 2013 04:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cuadue/5596871 to your computer and use it in GitHub Desktop.
Save cuadue/5596871 to your computer and use it in GitHub Desktop.
Tornado Task implementation?
# OK here's one that spawns it's own Python thread per request. But this
# obviously won't work because I have one synchronous, non-threadsafe
# handle to /dev/i2c-1. So I have to schedule each transaction myself. This
# sounds a lot like what Tornado is already doing
from tornado import web
from tornado import gen
from functools import wraps
import threading
def run_async(func):
@wraps(func)
def wrapped(*args, **kwargs):
thread = Thread(target=func, args=args, kwargs=kwargs)
thread.start()
return thread
return wrapped
@run_async
def readwrite(number, callback=None):
assert callback
return args + 3
class Handler(web.RequestHandler):
def get(self):
number = yield gen.Task(readwrite, 10)
self.write(number)
# result = yield gen.Task(func, args)
# is equivalent to
# func(args, callback=(yield gen.Callback(key)))
# result = yield gen.Wait(key)
# The first yield gives control back to tornado. At it's next convenience,
# the callback will be called and control restored to my program.
# My program will then start my own asynchronous task func().
# comm.py
import threading
from Queue import Queue
__queue_in = threading.Queue()
__thread = threading.Thread()
__lock = threading.RLock()
__halt = False
def __comm_enqueue(func, args, callback=None):
queue_in.put((func, args, callback))
def __read_word(addr, cmd):
import smbus
def __write_word(addr, cmd, val):
import smbus
def __main():
func, args, callback = queue_in.get()
callback(func(args))
with __lock:
if __halt:
return
__thread = threading.thread(target=__main)
def run():
__thread.run()
def join():
global __halt
with __lock:
__halt = True
__thread.join()
def read_word(cmd, callback=None):
__comm_enqueue(__read_word, [addr, cmd], callback)
def write_word(cmd, val, callback=None)
__comm_enqueue(__write_word, [addr, cmd, val], callback)
# server.py
import comm
comm.run()
class Handler(web.RequestHandler):
def get(self, addr, cmd):
result = yield gen.Task(comm.read_word, cmd)
self.write('addr 0x%02x cmd 0x%02x read 0x%04x' % (
addr, cmd, result))
# tornado stuff
try:
ioloop.run()
finally:
comm.join()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment