Задать вопрос
@to_east

Python вызов асинхронной функции с периодичностью?

Вобщем код:
import asyncio
from dataclasses import dataclass
import time
from datetime import datetime
from random import randint


@dataclass
class State:
    value: int


async def delayer(seconds: int):
    while True:
        interval = seconds * 1e+9
        delay = interval - (time.time_ns() % interval)
        yield await asyncio.sleep(delay * 1e-9)


async def update(state, interval):
    async for _ in delayer(interval):
        new_value = randint(1, 100)
        state.value += new_value
        print(f"{datetime.now()} update {state.value}")


async def main():
    state = State(0)

    asyncio.create_task(update(state, 5))

    while True:
        print(f"{datetime.now()} main {state.value}")
        await asyncio.sleep(.5)


if __name__ == '__main__':
    asyncio.run(main())

Казалось бы все вроде логично, но посмотрев на вывод, увидел вот это:
...
01. 2025-05-15 14:05:39.308481 main 391
02. 2025-05-15 14:05:39.811125 main 391
03. 2025-05-15 14:05:40.001140 update 436
04. 2025-05-15 14:05:40.315979 main 436
05. 2025-05-15 14:05:40.830168 main 436
06. 2025-05-15 14:05:41.330853 main 436
07. 2025-05-15 14:05:41.845188 main 436
08. 2025-05-15 14:05:42.346309 main 436
09. 2025-05-15 14:05:42.860398 main 436
10. 2025-05-15 14:05:43.361397 main 436
11. 2025-05-15 14:05:43.863503 main 436
12. 2025-05-15 14:05:44.364032 main 436
13. 2025-05-15 14:05:44.869065 main 436
14. 2025-05-15 14:05:44.994269 update 471
15. 2025-05-15 14:05:45.009148 update 523
16. 2025-05-15 14:05:45.382439 main 523
17. 2025-05-15 14:05:45.889243 main 523
18. 2025-05-15 14:05:46.395340 main 523
19. 2025-05-15 14:05:46.895351 main 523
20. 2025-05-15 14:05:47.396639 main 523
21. 2025-05-15 14:05:47.897962 main 523
22. 2025-05-15 14:05:48.401170 main 523
...

В 14 и 15-ых строках сработали вызовы без необходимой задержки, в 14-ой строке если посмотреть на время, то кажется что функция "недосыпает" отведенное время. Причем delayer без проблем работает с простой функцией, а начинаешь добавлять логику, таски - появляются задержки, отсюда недосып функции.
  • Вопрос задан
  • 116 просмотров
Подписаться 2 Простой 20 комментариев
Пригласить эксперта
Ответы на вопрос 1
fenrir1121
@fenrir1121
Начни с документации
Кто попадет на эту страницу: проблема кода в сомнительной логике расчета задержки, которая может быть околонулевой.
Не пишите свои велосипеды, если нужны периодические асинхронные задачи используйте Sheduling tasks в taskiq
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы