fix(mounts): 3 min 15 s hingen in EINER Zeile - os.makedirs auf dem toten Mount
Ampel / ampel (push) Successful in 29s

Nachtrag, weil die letzte Runde die Wiederanbindung nicht schneller machte
(202 s statt 150 s). Die Zeitstempel im Log zeigten, wo die Zeit sitzt:

  12:53:56  API gestartet
  12:54:03  "antwortet nicht - wird neu verbunden"    <- Erkennung: 7 s, gut
  12:57:18  "eingehaengt"                             <- Reparatur: 3 min 15 s

Die Erkennung war also schon schnell; die REPARATUR fraess die Zeit. Und zwar
nicht in den Mount-Versuchen, sondern in der ersten Zeile von mounten():

  os.makedirs(ziel, exist_ok=True)

`exist_ok` prueft mit os.path.isdir, und ein `stat` auf einen toten CIFS-Mount
blockiert im Kernel bis zum SMB-Timeout. Ausgerechnet der Aufruf, der nur "lege
den Ordner an, falls er fehlt" bedeutet, hing drei Minuten - BEVOR irgendeine der
sorgfaeltig begrenzten Pruefungen dran war. Dritter Fund derselben Sorte an einem
Tag: os-Aufruf auf einen Netzpfad ohne Zeitgrenze.

Jetzt klaert `pfad_lage()` die Lage mit einem abbrechbaren Kind-Prozess
(`timeout 4 ls -d`, drei Antworten: da / weg / unklar), und makedirs laeuft nur
bei "weg". Dieselbe Falle in `reparieren()` (os.path.ismount als Vorbedingung -
gebraucht wird es nicht, `umount -l` auf einen leeren Pfad kostet nichts) und in
`aushaengen()` (ismount + rmdir).

Dazu steht die DAUER jetzt im Log ("neu verbunden (4.2s)"). Sie war die
entscheidende Spur; wer sie ablesen kann, muss sie nicht rekonstruieren.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-26 15:01:09 +02:00
parent 2a90538473
commit 58f4991d92
3 changed files with 170 additions and 28 deletions
+10 -2
View File
@@ -447,6 +447,7 @@ def _mounts_nachsehen() -> None:
if vorher is not False:
db.add_log("warning", "mounts",
f"{name}: antwortet nicht — wird neu verbunden")
begonnen = time.monotonic()
try:
mount_verwaltung.reparieren(
name, eintrag["typ"], eintrag["quelle"],
@@ -454,9 +455,16 @@ def _mounts_nachsehen() -> None:
eintrag.get("passwort") or "",
)
_MOUNT_STAND[name] = True
db.add_log("success", "mounts", f"{name}: neu verbunden")
# Die DAUER mit ins Log: Sie war die entscheidende Spur, als eine
# Wiederanbindung drei Minuten brauchte (ein `stat` auf dem toten
# Mount). Steht sie da, muss man sie nicht erst rekonstruieren.
db.add_log("success", "mounts",
f"{name}: neu verbunden ({time.monotonic() - begonnen:.1f}s)")
except Exception as e:
db.add_log("warning", "mounts", f"{name}: Neuverbinden fehlgeschlagen — {e}")
db.add_log(
"warning", "mounts",
f"{name}: Neuverbinden fehlgeschlagen nach "
f"{time.monotonic() - begonnen:.1f}s — {e}")
async def _rohdaten_schleife():