feat: pace startup housekeeper runs

This commit is contained in:
Marcel Peterkau
2026-06-21 21:42:38 +02:00
parent fc042f6711
commit e6200f4a02
5 changed files with 56 additions and 4 deletions
+1
View File
@@ -29,6 +29,7 @@
"Splash-Screen auf das eingebettete CCMA-Hintergrundmotiv umgestellt und redundante Titeltexte entfernt.",
"Konfigurierbare Mindestanzeigezeit des Splash-Screens mit fünf Sekunden Standardwert ergänzt.",
"Theme-unabhängigen Splash-Fortschrittsbalken in Bild-Blau mit Silberrahmen und zeitbasiertem Fortschritt eingeführt.",
"Splash-Start verteilt seine Mindestanzeigezeit als optionales Mitglieder-Delay auf den Hausmeisterlauf, um insbesondere Netzwerk-Dateisysteme zu entlasten.",
"Hausmeister um konfigurierbare Geburtstags- und Mitgliedsjubiläumsmeldungen erweitert.",
"Statusänderungen werden mit altem und neuem Klartextwert in der Mitgliederchronik protokolliert.",
"Fensterposition, normaler Fensterzustand und Maximierung werden gespeichert; der Splash startet auf dem zuletzt verwendeten Monitor.",
+20 -2
View File
@@ -2,7 +2,9 @@ from __future__ import annotations
import copy
import json
import math
import os
import time
from contextlib import contextmanager
from dataclasses import dataclass, field
from datetime import date, datetime
@@ -54,8 +56,14 @@ class Housekeeper:
self.state_path = repository.root / "housekeeper.json"
self.lock_path = repository.root / ".housekeeper.lock"
def run(self, today: date | None = None) -> list[HousekeeperFinding]:
def run(
self,
today: date | None = None,
*,
member_delay: float = 0.0,
) -> list[HousekeeperFinding]:
current_date = today or date.today()
delay = _non_negative_delay(member_delay)
with _exclusive_lock(self.lock_path):
original = self._load_state()
working = copy.deepcopy(original)
@@ -69,7 +77,9 @@ class Housekeeper:
rules = load_rules(self.repository.root)
repository_config = self.repository.get_configuration()
for member_id in sorted(member_ids):
for index, member_id in enumerate(sorted(member_ids)):
if index and delay:
time.sleep(delay)
try:
member, contributions = self.repository.preflight_member_record(member_id)
except RepositoryError as exc:
@@ -405,6 +415,14 @@ def _remove_orphaned_member_items(items: dict[str, dict[str, Any]], member_ids:
del items[key]
def _non_negative_delay(value: float) -> float:
try:
delay = float(value)
except (TypeError, ValueError):
return 0.0
return max(0.0, delay) if math.isfinite(delay) else 0.0
@contextmanager
def _exclusive_lock(path: Path):
path.parent.mkdir(parents=True, exist_ok=True)
+13 -1
View File
@@ -119,10 +119,16 @@ class SplashScreen(tk.Toplevel):
errors = self.repository.validate()
self._messages.put(("status", "Baue Suchindex …"))
self.repository.list_members()
member_count = len(self.repository.list_member_ids())
findings = []
if self.run_housekeeper:
self._messages.put(("status", "Starte Hausmeister …"))
findings = Housekeeper(self.repository, self.housekeeper_settings).run()
findings = Housekeeper(self.repository, self.housekeeper_settings).run(
member_delay=_member_delay_for_splash(
self.minimum_display_seconds,
member_count,
)
)
result = StartupResult(self.repository, errors, findings)
self._messages.put(("result", result))
except Exception as exc:
@@ -265,3 +271,9 @@ def _progress_value(elapsed: float, minimum_seconds: float, startup_finished: bo
if startup_finished:
return elapsed_ratio * 100.0
return elapsed_ratio * 95.0
def _member_delay_for_splash(minimum_seconds: float, member_count: int) -> float:
if minimum_seconds <= 0 or member_count <= 0:
return 0.0
return minimum_seconds / member_count