Created
May 17, 2013 04:08
-
-
Save cuadue/5596871 to your computer and use it in GitHub Desktop.
Tornado Task implementation?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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