I'm having a hard time understanding how the AsyncIOScheduler works, and how is it non blocking?
If my job is executing a blocking function, will the AsyncIOScheduler
be blocking?
And what if I use AsyncIOScheduler
with ThreadPoolExecutor
? How does that work? Can I await the job execution?
AsyncIOScheduler was meant to be used with the AsyncIO event loop. By default, it will run jobs in the event loop's thread pool. If you have an application that runs on an AsyncIO event loop, you will want to use this scheduler. Default executor.
Advanced Python Scheduler (APScheduler) is a Python library that lets you schedule your Python code to be executed later, either just once or periodically. You can add new jobs or remove old ones on the fly as you please.
The max_instances only tells you how many concurrent jobs you can have. APScheduler has three types of triggers: date interval cron. interval and cron repeat forever, date is a one-shot on a given date.
Using some Internet resources I found some useful facts. Hope it will help you.
A typical APScheduler instance houses tens of jobs, which execute regular Python functions. There is no limit on the number of jobs an APScheduler instance can schedule; it only depends on the actual load of the machine. By default, APScheduler stores all jobs in-memory. If you want your jobs to survive from process restarts and keep triggering from the last time there were triggered, you can store these jobs in a database, such as any RDBMS, Redis, MongoDB, etc.
Depending on how your applications run, it can run as a thread, or an asyncio task, or else. When initialized, APScheduler doesn't do anything unless you add the Python functions as jobs. Once all the jobs are added, you need to "start" the scheduler. For a simple example of how to use APScheduler, here is a snippet of code that just works.
from urllib.request import urlopen
from apscheduler.schedulers.blocking import BlockingScheduler
scheduler = BlockingScheduler()
@scheduler.scheduled_job("interval", seconds=10)
def keep_warm():
urlopen("https://enqueuezero.com", timeout=10)
scheduler.start()
This makes sure a URL is requested every 10 seconds. The program runs as a blocking process. If you want to co-exist them with your application, you can consider using BackgroundScheduler
, AsyncIOScheduler
, etc.
BackgroundScheduler
.from datetime import datetime
import time
import os
from apscheduler.schedulers.background import BackgroundScheduler
def tick():
print('Tick! The time is: %s' % datetime.now())
if __name__ == '__main__':
scheduler = BackgroundScheduler()
scheduler.add_job(tick, 'interval', seconds=3)
scheduler.start()
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
try:
# This is here to simulate application activity (which keeps the main thread alive).
while True:
time.sleep(2)
except (KeyboardInterrupt, SystemExit):
# Not strictly necessary if daemonic mode is enabled but should be done if possible
scheduler.shutdown()
asyncio
compatible scheduler to schedule a job that executes on 3-second intervals.import asyncio
import os
from datetime import datetime
from apscheduler.schedulers.asyncio import AsyncIOScheduler
def tick():
print('Tick! The time is: %s' % datetime.now())
if __name__ == '__main__':
scheduler = AsyncIOScheduler()
scheduler.add_job(tick, 'interval', seconds=3)
scheduler.start()
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
# Execution will block here until Ctrl+C (Ctrl+Break on Windows) is pressed.
try:
asyncio.get_event_loop().run_forever()
except (KeyboardInterrupt, SystemExit):
pass
Based on the documentation an AsyncIOScheduler is executed in an event loop.
It is non-blocking because it will simply add itself to the event loop and wait until you start it.
Once the event loop is started it will run asynchronously.
from apscheduler.schedulers.asyncio import AsyncIOScheduler
import asyncio
async def job():
print('hi')
scheduler = AsyncIOScheduler()
scheduler.add_job(job, "interval", seconds=3)
scheduler.start()
asyncio.get_event_loop().run_forever()
Output
Run time of job "job (trigger: interval[0:00:03], next run at: 2020-07-27 14:06:39 -03)" was missed by 0:00:02.542515
hi
hi
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With