Is it possible to schedule an async and sync function at the same time?

Viewed 34

Code of reference:

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from telegram.ext import ApplicationBuilder

def function_one(args):
    #DO SOMETHING

async def function_two(args):
    await #DO SOMETHING ELSE

scheduler_one = BackgroundScheduler()
scheduler_two = AsyncIOScheduler()

scheduler_one.add_job(function_one, 'interval', minutes = 5, args = ( ,))
scheduler_two.add_job(function_two, 'interval', minutes = 1, args = ( ,))

if __name__ == "__main__":

    application = ApplicationBuilder().token(API_KEY).build()

    scheduler_one.start()
    scheduler_two.start()

    application.run_polling()

Module versions:

  • Python v3.10.6
  • python-telegram-bot v20.0a1
  • apscheduler v3.9.1

Output: Only scheduler_two starts working, whereas scheduler_one will be ignored. Therefore, only one scheduler is activated.

Description of the problem: I need both function_one and function_two to work periodically. function_two depends on the python-telegram-bot Bot class which needs to be awaited.

Attempts:

  • I have tried using scheduler_one for both but I get an error message regarding function_two
/app/.heroku/python/lib/python3.10/concurrent/futures/thread.py:85: RuntimeWarning: coroutine 'function_two' was never awaited
2022-09-15T14:46:30.247039+00:00 app[worker.1]:   del work_item
2022-09-15T14:46:30.247040+00:00 app[worker.1]: RuntimeWarning: Enable tracemalloc to get the object allocation traceback
  • Then, I tried using scheduler_two for both, but only function_two works.

  • Finally, I tried calling function_one inside of function_two but it wouldn't work either.

Therefore, my question is whether there is any way at all to run these two functions at the same time or any workarounds?

1 Answers

I'd like to point out that python-telegram-bot comes with the built-in JobQueue which is in fact based on APScheduler. So setting up a scheduler yourself is likely not even necessary. Note that in v13.x, PTB uses the BackgroundScheduler, while in v20.x (currently in pre-release mode), PTB uses the AsyncIOScheduler, since v20 made the transition to asyncio.

Regarding coroutine functions vs normal functions as job callbacks, I have to comments:

  • defining function_one as coroutine function as well will not affect any of the code within the function and that way you can directly use it in the AsyncIOScheduler (or the JobQueue)
  • BackgroundScheduler is based on threading. I would generally avoid mixing threading with asyncio. So if function_one performs any I/O intensive tasks, I'd recommend to rework those to an asyncio based scheme.
Related