как не дожидаться окончания асинхронной функции

Делаю бота для игры в мафию, и чтобы завершить ночь должно либо пройти 90 секунд, либо когда все сделают свои ночные действия

@game_process_router.callback_query(CallbackFactory.filter())
async def night_actions_handler(callback: CallbackQuery, callback_data: CallbackFactory):
    #какая-то логика
    ...
    #какая-то логика
    global night_callbacks
    night_callbacks += 1
    if(night_callbacks == len(registration.live_players)):
        await bot.send_message(chat_id = registration.game_chat_id, text = f"Город просыпается")
    await callback.answer()

я понимаю что нужно использовать await asyncio.sleep(90) но если игроки нажмут свои действия раньше 90с то как сказать питону чтобы он не ждал эти 90


Ответы (3 шт):

Автор решения: PaveTranquil

То, что вы хотите, можно реализовать через таймеры в apscheduler. Создайте задачу на выполнение через 90 секунд, которая прервёт ночь. При этом aiogram будет продолжать работать дальше и вы сможете обрабатывать события от игроков. И как только все нажмут свои кнопки раньше 90 секунд, вы сможете немедленно выполнить и удалить отложенную задачу по ID или из JobStore'а (job.remove, job.func(*job.args, **job.kwargs)).

→ Ссылка
Автор решения: eri

Делай массив questions из asyncio.Future() на каждый вопрос пользователю.

Дожидайся через

done, pending = await asyncio.wait(questions, timeout=90)

В done будут отмеченные, в pending просроченные.

Установить ответ в Future например через fu.set_result({"user":id, "answer": data})

→ Ссылка
Автор решения: Flectere

Всё, я со всем разобрался:

trigger = DateTrigger(run_date=datetime.now() + timedelta(seconds = 90))
global job
job = apscheduler.add_job(func = stop_night_func, trigger=trigger)

и внутри обработчика:

if(night_callbacks == len(registration.live_players)):
    apscheduler.reschedule_job(job_id = job.id, trigger = 'date', run_date = datetime.now())
→ Ссылка