51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
import asyncio
|
|
import logging
|
|
from datetime import datetime
|
|
from typing import Awaitable, Callable
|
|
|
|
from .schedule import should_run
|
|
from .service import ORIGIN_AUTO, RetentionBusy, RetentionService
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
START_DELAY = 60.0
|
|
CHECK_INTERVAL = 900.0
|
|
|
|
|
|
class RetentionRunner:
|
|
def __init__(self, service: RetentionService, clock: Callable[[], datetime] = datetime.now,
|
|
sleep: Callable[[float], Awaitable[None]] = asyncio.sleep, start_delay: float = START_DELAY,
|
|
interval: float = CHECK_INTERVAL):
|
|
self._service = service
|
|
self._clock = clock
|
|
self._sleep = sleep
|
|
self._start_delay = start_delay
|
|
self._interval = interval
|
|
self._last_attempt: float | None = None
|
|
|
|
async def tick(self, startup: bool) -> bool:
|
|
record = await asyncio.to_thread(self._service.last_run)
|
|
known = [ts for ts in (record.ts if record else None, self._last_attempt) if ts is not None]
|
|
now = self._clock()
|
|
if not should_run(now, max(known) if known else None, startup):
|
|
return False
|
|
self._last_attempt = now.timestamp()
|
|
try:
|
|
await asyncio.to_thread(self._service.run, ORIGIN_AUTO)
|
|
except RetentionBusy:
|
|
log.info("Aufbewahrung läuft bereits")
|
|
except Exception:
|
|
log.exception("Aufbewahrung fehlgeschlagen")
|
|
return True
|
|
|
|
async def run(self) -> None:
|
|
await self._sleep(self._start_delay)
|
|
startup = True
|
|
while True:
|
|
try:
|
|
await self.tick(startup)
|
|
except Exception:
|
|
log.exception("Aufbewahrung: Prüfung fehlgeschlagen")
|
|
startup = False
|
|
await self._sleep(self._interval)
|