fix(transcode): "Abbrechen" wirkt sofort statt erst beim naechsten Prozent
Ampel / ampel (push) Failing after 28s
Ampel / ampel (push) Failing after 28s
Fund des Commanders am laufenden Akira-Job (Nachtrag im vorigen Savepoint):
Job stand auf 'canceling', HandBrake lief weiter. Gemessen 3,4 Minuten
zwischen Anforderung (18:30:17) und Bestaetigung (18:33:38) - bei langsamerem
Fortschritt entsprechend mehr.
Ursache genau wie dort beschrieben: Der Abbruch wurde nur in
datei_fortschritt geprueft, und diese Closure stieg oben sofort wieder aus,
wenn sich die Prozentzahl nicht geaendert hatte ("if gesamt == letzter[0]:
return"). Bei einem Prozent je halber Stunde hing der Abbruch also an einem
Ereignis, das eine halbe Stunde lang nicht eintrat.
run_handbrake bekommt jetzt einen eigenen abbruch_cb neben progress_cb -
dasselbe Muster, das run_makemkv schon fuer log_cb benutzt, und aus
demselben Grund: der Fortschritts-Kanal verwirft Aufrufe. Er wird bei JEDER
Ausgabezeile aufgerufen und im Worker auf 5 s gedrosselt.
Nebeneffekt, der genauso wichtig ist: Er greift auch waehrend des
Scan-Durchlaufs, der ueberhaupt keine Encode-Prozente liefert. Dort war ein
Abbruch vorher grundsaetzlich unmoeglich - und seit die Prozent-Regex den
Scan korrekt ignoriert, waere das sonst sogar schlimmer geworden.
Die Leseschleife ist als _handbrake_schleife() herausgezogen, damit die
Reihenfolge (Abbruch VOR Fortschritt) ohne echtes HandBrake pruefbar ist.
Der Test belegt: zwei Scan-Zeilen genuegen fuer den Abbruch, es muss NICHT
auf eine Encode-Zeile gewartet werden.
Savepoint nachgezogen: Der Encode laeuft nicht mehr, ein Deploy ist
gefahrlos moeglich, und die alte "SOFORT ENTSCHEIDEN"-Passage (Platte
laeuft voll, wenn der Job fertig wird) ist damit gegenstandslos. Neu darin:
die drei Wege fuer UHD, und die Warnung, dass eine /proc-Suche nach
"HandBrake" die eigene Shell mittrifft - zwei Fehlalarme in dieser Sitzung.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -225,3 +225,50 @@ def test_preset_fuer_ohne_einstellungen_nimmt_den_eingebauten_standard():
|
||||
assert preset_fuer("", None) == DEFAULT_HB_PRESET
|
||||
assert preset_fuer(None, {}) == DEFAULT_HB_PRESET
|
||||
assert preset_fuer("cd", {"transcodePresetUhd": "egal"}) == DEFAULT_HB_PRESET
|
||||
|
||||
|
||||
def test_handbrake_prueft_abbruch_bei_jeder_zeile_nicht_nur_bei_fortschritt():
|
||||
"""Befund 25.07.2026 (am laufenden Akira-Job beobachtet): Der Abbruch hing
|
||||
am Fortschritts-Callback, und der stieg bei unveraenderter Prozentzahl
|
||||
sofort aus. Bei einem 4K-Encode mit einem Prozent je halber Stunde sah
|
||||
„Abbrechen" minutenlang wirkungslos aus (gemessen: 3,4 min).
|
||||
|
||||
Der Abbruch-Kanal muss deshalb JEDE Ausgabezeile sehen — auch die des
|
||||
Scan-Durchlaufs, der gar keine Encode-Prozente liefert.
|
||||
"""
|
||||
import ripping
|
||||
|
||||
zeilen = [
|
||||
"Scanning title 1 of 1, preview 1, 10.00 %\n",
|
||||
"Scanning title 1 of 1, preview 2, 20.00 %\n",
|
||||
"Encoding: task 1 of 1, 0.00 %\n",
|
||||
"Encoding: task 1 of 1, 0.00 %\n",
|
||||
]
|
||||
gesehen = []
|
||||
|
||||
class FakeProcess:
|
||||
def __init__(self):
|
||||
self.stdout = iter(zeilen)
|
||||
self.returncode = 0
|
||||
self.getoetet = False
|
||||
|
||||
def kill(self):
|
||||
self.getoetet = True
|
||||
|
||||
def wait(self):
|
||||
return 0
|
||||
|
||||
prozess = FakeProcess()
|
||||
|
||||
def abbruch_cb():
|
||||
gesehen.append(1)
|
||||
if len(gesehen) == 2: # beim zweiten Mal abbrechen
|
||||
raise ripping.RipAbbruch()
|
||||
|
||||
ergebnis = ripping._handbrake_schleife(prozess, "/x.mkv", abbruch_cb, None)
|
||||
|
||||
assert ergebnis["status"] == "cancelled"
|
||||
assert prozess.getoetet is True
|
||||
# Zwei Scan-Zeilen genuegten — es musste NICHT auf eine Encode-Zeile gewartet
|
||||
# werden. Genau das war der Fehler.
|
||||
assert len(gesehen) == 2
|
||||
|
||||
Reference in New Issue
Block a user