Home > Software design >  Is it possible to schedule an async and sync function at the same time?
Is it possible to schedule an async and sync function at the same time?

Time:09-16

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?

CodePudding user response:

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