Вобщем код:
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 без проблем работает с простой функцией, а начинаешь добавлять логику, таски - появляются задержки, отсюда недосып функции.