fix(worker): kein CMD-Blitzen mehr - und die 7200-Sekunden-Meldung ist erklaert
Ampel / ampel (push) Successful in 31s
Ampel / ampel (push) Successful in 31s
Zwei Meldungen, beide auf dieselbe Wurzel zurueckgefuehrt: Der Worker startet
Konsolenprogramme, und das hat unter Windows Nebenwirkungen.
1. "Es geht immer alle paar Sekunden ne CMD auf." Kein Geist, sondern der
HERZSCHLAG. Der Worker laeuft als pythonw.exe, also ohne eigene Konsole. Wer
ohne Konsole ein Konsolenprogramm startet, bekommt von Windows eine NEUE - und
die ist sichtbar. `capture_output=True` hilft nicht: es leitet die Datenstroeme
um, unterdrueckt aber kein Fenster. Und caps.py fragt jede Minute
`HandBrakeCLI --help`, `--preset-list` und `--version` ab, dazu makemkvcon aus
der Schluessel-Automatik: vier bis fuenf Fenster pro Minute, in Schueben.
Neues winlauf.py haelt CREATE_NO_WINDOW an EINER Stelle; alle elf Aufrufe in
caps.py, ripping.py und schluessel.py benutzen es. Auf Linux ist der Wert 0 und
creationflags=0 eine Nulloperation - im Worker-Container gegengeprueft, damit
derselbe Code auf beiden Seiten laeuft.
2. Die 7200 Sekunden sind CELERYS EIGENE UMRECHNUNG, nicht die Uhren. Erst fiel
auf, dass die Sekundenbruchteile nur 40 ms auseinanderliegen (.177269 vs
.134799) - derselbe Augenblick, zweimal verschieden gerechnet. Die Quelle sagt
warum (celery/utils/time.py):
def utcoffset(): # Sekunden WEST von UTC, in Stunden
return time.altzone // 3600 # CEST -> -2 ; UTC -> 0
def adjust_timestamp(ts, offset, here=utcoffset):
return ts - (offset - here()) * 3600
Absender VM (offset 0), Empfaenger Windows-PC (here() = -2):
ts - (0 - (-2)) * 3600 = ts - 7200. Celery verschiebt den empfangenen Stempel
also selbst und vergleicht ihn dann mit der eigenen Uhr. Die Annahme dahinter -
Ereignisse truegen Ortszeit - stimmt nicht, `Event()` stempelt Epoch.
Abhilfe gemessen, nicht geraten: Mit TZ=UTC meldet Windows utcoffset 0
(timezone=0, isdst=0 - auf dem Commander-PC geprueft), damit wird die
Umrechnung zur Nulloperation. Beide .bat-Dateien setzen es jetzt. Nebeneffekt
ist erwuenscht: Der Worker rechnet dann in derselben Zone wie die VM und wie
Rippys UI.
Fuer Rippy war die Meldung ohnehin folgenlos - /capabilities fragt per
Celery-Ping (Frage/Antwort, ohne Zeitstempel), nicht ueber die
Gossip-Ereignisse. Aber eine Warnung, die bei jedem Blick ins Log steht und
nichts bedeutet, kostet Vertrauen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
"""Kind-Prozesse starten, ohne dass ein Konsolenfenster aufblitzt.
|
||||
|
||||
## Der Befund, der das nötig gemacht hat (26.07.2026)
|
||||
|
||||
Commander: *„Es geht übrigens immer alle paar Sekunden ne CMD auf."* Und er hatte
|
||||
recht — es war kein Geist, sondern der Herzschlag des Workers.
|
||||
|
||||
Der Windows-Worker läuft als `pythonw.exe`, also ohne eigene Konsole (das Tray
|
||||
startet ihn mit CREATE_NO_WINDOW). Startet ein Prozess OHNE Konsole ein
|
||||
Konsolenprogramm, legt Windows dafür eine NEUE Konsole an — und die ist sichtbar.
|
||||
`capture_output=True` hilft nicht: Es leitet die Datenströme um, unterdrückt aber
|
||||
kein Fenster.
|
||||
|
||||
Und der Worker startet solche Programme oft: `caps.py` fragt jede Minute
|
||||
`HandBrakeCLI --help`, `--preset-list` und `--version` ab, dazu kommt die
|
||||
Schlüssel-Automatik mit `makemkvcon`. Vier bis fünf Fenster pro Minute, in
|
||||
Schüben — genau das „alle paar Sekunden".
|
||||
|
||||
## Warum eine eigene Datei
|
||||
|
||||
Damit es an EINER Stelle richtig ist. Die betroffenen Aufrufe stehen in caps.py,
|
||||
ripping.py und schluessel.py; jeder hätte das Flag einzeln vergessen können, und
|
||||
genau so ist es passiert. Auf Linux ist `CREATE_NO_WINDOW` nicht vorhanden und
|
||||
`creationflags=0` eine Nulloperation — im Worker-Container gegengeprüft, damit
|
||||
derselbe Code auf beiden Seiten läuft.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
|
||||
# Auf Windows das Flag, auf Linux 0 (dort wird creationflags=0 akzeptiert und
|
||||
# ignoriert — am 26.07.2026 im Worker-Container gemessen).
|
||||
OHNE_FENSTER = getattr(subprocess, "CREATE_NO_WINDOW", 0)
|
||||
Reference in New Issue
Block a user