Using multiple threads with tornado PeriodicCallback

70 Views Asked by At

I have an application that needs 3 periodic callbacks (Only one of them really interacts with the ioloop because it pushes data to the via the websocket)

def make_app():
  return tornado.web.Application([
                (r"/websocket", WebsocketHandler),
                (r"/getData", DataRequestHandler),
  ])

if __name__ == '__main__':
  tornado.ioloop.PeriodicCallback(callback=calculator1, callback_time=500).start()
  tornado.ioloop.PeriodicCallback(callback=calculator2, callback_time=1000).start()
  tornado.ioloop.PeriodicCallback(callback=push, callback_time=1000).start()
  tornado.ioloop.IOLoop.current().start()

I find that all of this is run in the main thread The problem is then that because calculator2 could take more that 500ms to run, it blocks the thread and calculator1 may not run at the next 500ms because thread was blocked

How do I properly schedule calculator1 and calculator2 periodic functions in different threads other than the main thread?

I am not certain how to make the functions run in different threads other than the ioloop thread

1

There are 1 best solutions below

1
xyres On

You can use Tornado's run_in_executor() method to run blocking tasks in separate threads.

You'll need to create another function to run periodically which will execute the actual calculator1 function in another thread.

# create a thread pool
from concurrent.futures import ThreadPoolExecutor

executor = ThreadPoolExecutor(max_workers=8)


def calculator1_runner():
    """This function is for calling the calculator1 function"""
    IOLoop.current().run_in_executor(executor, calculator1) 


# Register the runner function for periodic execution
tornado.ioloop.PeriodicCallback(
    callback=calculator1_runner,
    callback_time=500
).start()