fix(bg): Hintergrundarbeit reisst den Prozess nicht mehr mit
Das Vorschaubild entstand in einer nackten Goroutine. Chis Recoverer haengt
am Anfragebehandler und sieht davon nichts -- eine Panik im Bilddekodierer
nahm den ganzen Go-Prozess mit, ausgeloest durch einen gewoehnlichen
Upload. Die Bibliothek ist seit ef60497 aktuell; das schloss **diese**
Luecke. Dies hier schliesst die **Gattung**.
pkg/bg mit zwei Funktionen, und der Unterschied ist keine Feinheit:
* bg.Go(name, fn) -- Goroutine, die eine Panik ueberlebt
* bg.Run(name, fn) -- dasselbe ohne eigene Goroutine, fuer Schleifen
Faengt man eine Panik um den **ganzen** Arbeiter ab, ueberlebt der Prozess
-- aber der Arbeiter ist tot, und von da an wird still keine Datei mehr
erkannt. Der OCR-Arbeiter sichert deshalb jeden **Auftrag** einzeln ab.
Umgestellt: Vorschaubild, Bestand nachtragen, Freigabe-Zaehler,
Speicherbereinigung, OCR-Arbeiter. Eine nackte Goroutine bleibt mit
Begruendung im Code -- die Signalbehandlung; ein recover braechte dort
nichts, weil main ohnehin wartete.
Aufgefangene Paniken werden mit Stapel und Herkunft protokolliert. Vier
Tests, darunter der wichtige: Eine Schleife laeuft nach einer Panik im
dritten Durchgang weiter.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
89f0817dcb
commit
c26bcba012
7 files changed
+156
-17
No files matched your search
@@ -0,0 +1,45 @@
|
||||
package bg
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRunFaengtPanikAuf(t *testing.T) {
|
||||
// Ohne das recover in Run stürbe hier der Testprozess – das ist zugleich
|
||||
// die Aussage des Tests.
|
||||
Run("test", func() { panic("absichtlich") })
|
||||
}
|
||||
|
||||
func TestRunLaesstErgebnisDurch(t *testing.T) {
|
||||
gelaufen := false
|
||||
Run("test", func() { gelaufen = true })
|
||||
if !gelaufen {
|
||||
t.Fatal("fn wurde nicht ausgeführt")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoLaeuftUndUeberlebt(t *testing.T) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
Go("heil", func() { defer wg.Done() })
|
||||
Go("panisch", func() { defer wg.Done(); panic("absichtlich") })
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// Eine Schleife, in der ein Durchgang scheitert, muss weiterlaufen – das ist
|
||||
// der Grund, warum es Run neben Go gibt.
|
||||
func TestSchleifeLaeuftNachPanikWeiter(t *testing.T) {
|
||||
durchgaenge := 0
|
||||
for i := range 5 {
|
||||
Run("schritt", func() {
|
||||
durchgaenge++
|
||||
if i == 2 {
|
||||
panic("mittendrin")
|
||||
}
|
||||
})
|
||||
}
|
||||
if durchgaenge != 5 {
|
||||
t.Fatalf("nur %d von 5 Durchgängen", durchgaenge)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user