Task Scheduling
Equipment provides a powerful task scheduler build on top of the popular schedule library. It allows you to define recurring tasks at specific intervals or times using a human-readable syntax.
Scheduling Tasks
All your scheduled tasks should be defined in the run() method of your app/Scheduler.py class.
Common Scheduling Patterns
class Scheduler(Equipment):
def run(self) -> None:
# Run every minute
self.schedule.every(1).minutes.do(self.my_task)
# Run every hour at 30 minutes past the hour
self.schedule.every().hour.at(":30").do(self.my_task)
# Run daily at a specific time
self.schedule.every().day.at("10:30").do(self.my_task)
# Run every Monday
self.schedule.every().monday.do(self.my_task)
# Run every 5 to 10 minutes (random range)
self.schedule.every(5).to(10).minutes.do(self.my_task)
# Important: call super().run() to start the execution loop
super().run()
Scheduler & Queue Integration
A powerful pattern in Equipment is using the scheduler to push tasks into a background queue. This prevents the scheduler from blocking on long-running tasks.
def process_data():
# Long-running task
pass
class Scheduler(Equipment):
def run(self) -> None:
# Instead of calling process_data directly, we push it to the queue
self.schedule.every().hour.do(self.queue.push, process_data)
super().run()
Running the Scheduler
The scheduler runs in a separate process that stays alive indefinitely.
# Start the scheduler
python scheduler.py
Best Practices
- Keep tasks lightweight: If a task takes more than a few seconds, push it to a queue instead of running it directly in the scheduler.
- Use Centralized Logging: Always use
self.logwithin your scheduler tasks to track execution and errors. - Handle Exceptions: The scheduler loop can stop if a task raises an unhandled exception. Wrap your task logic in
try...exceptblocks. - Timezones: Be aware that the
schedulelibrary uses the system's local time by default.