decorator.py 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. """HACS Decorators."""
  2. from __future__ import annotations
  3. import asyncio
  4. from functools import wraps
  5. from typing import TYPE_CHECKING, Any, Coroutine
  6. from ..const import DEFAULT_CONCURRENT_BACKOFF_TIME, DEFAULT_CONCURRENT_TASKS
  7. if TYPE_CHECKING:
  8. from ..base import HacsBase
  9. def concurrent(
  10. concurrenttasks: int = DEFAULT_CONCURRENT_TASKS,
  11. backoff_time: int = DEFAULT_CONCURRENT_BACKOFF_TIME,
  12. ) -> Coroutine[Any, Any, None]:
  13. """Return a modified function."""
  14. max_concurrent = asyncio.Semaphore(concurrenttasks)
  15. def inner_function(function) -> Coroutine[Any, Any, None]:
  16. @wraps(function)
  17. async def wrapper(*args, **kwargs) -> None:
  18. hacs: HacsBase = getattr(args[0], "hacs", None)
  19. async with max_concurrent:
  20. result = await function(*args, **kwargs)
  21. if (
  22. hacs is None
  23. or hacs.queue is None
  24. or hacs.queue.has_pending_tasks
  25. or "update" not in function.__name__
  26. ):
  27. await asyncio.sleep(backoff_time)
  28. return result
  29. return wrapper
  30. return inner_function