54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
import asyncio
|
|
import logging
|
|
import time
|
|
from typing import Awaitable, Callable
|
|
|
|
from ..models import Event, Key, StateRow
|
|
from ..mutes import Mute
|
|
from ..routing import Route
|
|
from .due import due_reminders
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
CHECK_INTERVAL_SECONDS = 60.0
|
|
|
|
|
|
class ReminderWorker:
|
|
def __init__(self, load_state: Callable[[], dict[Key, StateRow]], rules: Callable[[], list[Route]],
|
|
mutes: Callable[[float], list[Mute]], default_hours: Callable[[], int],
|
|
sink: Callable[[list[Event]], Awaitable[None]], mark: Callable[[str, str, int], None],
|
|
clock: Callable[[], float] = time.time, interval: float = CHECK_INTERVAL_SECONDS,
|
|
sleep: Callable[[float], Awaitable[None]] = asyncio.sleep):
|
|
self._load = load_state
|
|
self._rules = rules
|
|
self._mutes = mutes
|
|
self._default_hours = default_hours
|
|
self._sink = sink
|
|
self._mark = mark
|
|
self._clock = clock
|
|
self._interval = interval
|
|
self._sleep = sleep
|
|
|
|
async def tick(self) -> int:
|
|
now = int(self._clock())
|
|
rows = await asyncio.to_thread(self._load)
|
|
rules = await asyncio.to_thread(self._rules)
|
|
mutes = await asyncio.to_thread(self._mutes, now)
|
|
events = due_reminders(rows.values(), rules, mutes, self._default_hours(), now)
|
|
for event in events:
|
|
# Zeitpunkt zuerst festhalten: lieber eine Erinnerung zu wenig als eine doppelte nach Neustart.
|
|
await asyncio.to_thread(self._mark, event.host, event.service, now)
|
|
if events:
|
|
await self._sink(events)
|
|
return len(events)
|
|
|
|
async def run(self) -> None:
|
|
while True:
|
|
try:
|
|
await self.tick()
|
|
except asyncio.CancelledError:
|
|
raise
|
|
except Exception:
|
|
log.exception("Erinnerungen: Prüfung fehlgeschlagen")
|
|
await self._sleep(self._interval)
|