mirror of
https://gitea.com/gitea/act
synced 2026-05-01 01:27:48 +02:00
Recover from panics in parallel executor workers (#153)
The worker goroutines in `NewParallelExecutor` had no panic recovery. A panic in any executor (e.g. expression evaluation) would crash the entire runner process, leaving all steps stuck in the UI because the final status was never reported back. Add `defer`/`recover` in the worker goroutines to convert panics into errors that propagate through the normal error channel. Issue is present in latest `nektos/act` as well. Fixes https://gitea.com/gitea/act_runner/issues/371 (Partially generated by Claude) Reviewed-on: https://gitea.com/gitea/act/pulls/153 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-committed-by: silverwind <me@silverwind.io>
This commit is contained in:
@@ -3,6 +3,7 @@ package common
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime/debug"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@@ -110,7 +111,18 @@ func NewParallelExecutor(parallel int, executors ...Executor) Executor {
|
|||||||
for executor := range work {
|
for executor := range work {
|
||||||
taskCount++
|
taskCount++
|
||||||
log.Debugf("Worker %d executing task %d", workerID, taskCount)
|
log.Debugf("Worker %d executing task %d", workerID, taskCount)
|
||||||
errs <- executor(ctx)
|
// Recover from panics in executors to avoid crashing the worker
|
||||||
|
// goroutine which would leave the runner process hung.
|
||||||
|
// https://gitea.com/gitea/act_runner/issues/371
|
||||||
|
errs <- func() (err error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Errorf("panic in executor: %v\n%s", r, debug.Stack())
|
||||||
|
err = fmt.Errorf("panic: %v", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return executor(ctx)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
log.Debugf("Worker %d finished (%d tasks executed)", workerID, taskCount)
|
log.Debugf("Worker %d finished (%d tasks executed)", workerID, taskCount)
|
||||||
}(i, work, errs)
|
}(i, work, errs)
|
||||||
|
|||||||
Reference in New Issue
Block a user