Skip to content

Instantly share code, notes, and snippets.

@mayflaver
Created January 15, 2014 09:08
Show Gist options
  • Save mayflaver/8433074 to your computer and use it in GitHub Desktop.
Save mayflaver/8433074 to your computer and use it in GitHub Desktop.
tornado periodic
from functools import wraps, partial
from period import PeriodicCallback
from tornado.concurrent import run_on_executor, TracebackFuture, DummyExecutor
import tornado.ioloop
import tornado.web
from tornado.gen import coroutine
class PeriodicExecutor(object):
def submit(self, fn, *args, **kwargs):
future = TracebackFuture()
def handle_response(response):
future.set_result(response)
args = list(args)
args.append(handle_response)
args = tuple(args)
periodic = PeriodicCallback(partial(fn, *args), 1000, 5)
periodic.start()
return future
def shutdown(self, wait=True):
pass
class MainHandler(tornado.web.RequestHandler):
@coroutine
def get(self):
self.executor = PeriodicExecutor()
response = yield self.test("hello", ", world")
self.write(response)
@run_on_executor
def test(self, a, b, response_callback, periodic):
if periodic._count > 3:
return
periodic.stop()
response_callback(a+b)
if __name__ == "__main__":
application = tornado.web.Application([
(r"/", MainHandler),
])
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
from tornado.ioloop import IOLoop
from functools import partial
from tornado.gen import coroutine
class PeriodicCallback(object):
"""Schedules the given callback to be called periodically.
The callback is called every ``callback_time`` milliseconds.
`start` must be called after the `PeriodicCallback` is created.
"""
def __init__(self, callback, callback_time, count=None, io_loop=None, *args, **kwargs):
self.callback = partial(callback, self)
if callback_time <= 0:
raise ValueError("Periodic callback must have a positive callback_time")
self.callback_time = callback_time
self.io_loop = io_loop or IOLoop.current()
self._running = False
self._timeout = None
self._count = count
def start(self):
"""Starts the timer."""
self._running = True
self._next_timeout = self.io_loop.time()
self._timeout = self.io_loop.add_timeout(self._next_timeout, self._run)
def stop(self):
"""Stops the timer."""
self._running = False
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
def _run(self):
if not self._running:
return
try:
self.callback()
except Exception:
self.io_loop.handle_callback_exception(self.callback)
if self._count is not None and self._count <= 0:
return
self._schedule_next()
self._count -= 1
def _schedule_next(self):
if self._running:
current_time = self.io_loop.time()
while self._next_timeout <= current_time:
self._next_timeout += self.callback_time / 1000.0
self._timeout = self.io_loop.add_timeout(self._next_timeout, self._run)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment