Tornado服务器定时异步调用方案咨询:APScheduler还是原生实现?
Hey there! Let's break down your options for running an async function every 5 minutes in a Tornado server, and figure out which approach fits your needs best.
Option 1: Tornado Native Implementation
Tornado's core IOLoop has built-in timeout tools that let you build a recurring async task without any external dependencies. The trick is to use add_timeout recursively—after each task finishes, you schedule the next execution.
Example Code
import tornado.ioloop import tornado.web from datetime import timedelta async def my_async_task(): # Replace this with your actual async business logic print("Executing scheduled async task...") def schedule_recurring_task(): # Run the task right away on server startup (optional) tornado.ioloop.IOLoop.current().add_callback(my_async_task) # Schedule the next run 5 minutes later tornado.ioloop.IOLoop.current().add_timeout( timedelta(minutes=5), schedule_recurring_task ) class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Tornado Server with Native Scheduler Running") def make_app(): return tornado.web.Application([(r"/", MainHandler)]) if __name__ == "__main__": app = make_app() app.listen(8888) # Kick off the recurring task schedule_recurring_task() tornado.ioloop.IOLoop.current().start()
Pros & Cons
- Pros:
- No extra dependencies—uses Tornado's core functionality
- Seamless integration with Tornado's async IOLoop
- Lightweight and straightforward for simple fixed-interval tasks
- Cons:
- Limited flexibility (no support for cron expressions, no easy way to pause/resume tasks)
- No built-in task persistence or monitoring
- Requires custom logic if you need to adjust the interval or stop the task dynamically
Option 2: Using APScheduler
APScheduler is a robust scheduling library with first-class support for Tornado via the TornadoScheduler backend. It's perfect if you need more advanced scheduling features beyond a simple 5-minute interval.
Example Code
First, install the dependency:
pip install apscheduler
Then set up the scheduler with your Tornado app:
import tornado.ioloop import tornado.web from apscheduler.schedulers.tornado import TornadoScheduler async def my_async_task(): print("Executing scheduled async task with APScheduler...") class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Tornado Server with APScheduler Running") def make_app(): return tornado.web.Application([(r"/", MainHandler)]) if __name__ == "__main__": app = make_app() app.listen(8888) # Initialize a Tornado-compatible scheduler scheduler = TornadoScheduler() # Add an interval job that runs every 5 minutes scheduler.add_job(my_async_task, 'interval', minutes=5) scheduler.start() try: tornado.ioloop.IOLoop.current().start() except (KeyboardInterrupt, SystemExit): # Clean up the scheduler gracefully on shutdown scheduler.shutdown()
Pros & Cons
- Pros:
- Supports multiple scheduling types (interval, cron, one-time dates)
- Built-in task management (pause, resume, delete jobs dynamically)
- Optional task persistence (save jobs to a database for restarts)
- Scalable for complex needs (e.g., different intervals on weekdays vs weekends)
- Cons:
- Adds an external dependency to your project
- Slightly more setup overhead compared to the native approach
Final Recommendation
- Choose Tornado native if: You only need a simple, fixed 5-minute recurring task and want to keep your project lightweight with no extra dependencies.
- Choose APScheduler if: You anticipate needing flexible scheduling later (like cron patterns), want to manage tasks dynamically, or need features like task persistence/monitoring. It's the better long-term choice for complex use cases.
内容的提问来源于stack exchange,提问作者Peter Pik

