Quellcode durchsuchen

Handle panics that percolate up to the graceful module (#11291)

* Handle panics in graceful goroutines

Adds a some deferred functions to handle panics in graceful goroutines

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Handle panic in webhook.Deliver

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Handle panic in mirror.syncMirror

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
tags/v1.13.0-dev
zeripath vor 4 Jahren
Ursprung
Commit
4a04740daf
Es ist kein Account mit der E-Mail-Adresse des Committers verbunden
3 geänderte Dateien mit 50 neuen und 1 gelöschten Zeilen
  1. 34
    1
      modules/graceful/manager.go
  2. 8
    0
      modules/webhook/deliver.go
  3. 8
    0
      services/mirror/mirror.go

+ 34
- 1
modules/graceful/manager.go Datei anzeigen

func (g *Manager) RunWithShutdownFns(run RunnableWithShutdownFns) { func (g *Manager) RunWithShutdownFns(run RunnableWithShutdownFns) {
g.runningServerWaitGroup.Add(1) g.runningServerWaitGroup.Add(1)
defer g.runningServerWaitGroup.Done() defer g.runningServerWaitGroup.Done()
defer func() {
if err := recover(); err != nil {
log.Critical("PANIC during RunWithShutdownFns: %v\nStacktrace: %s", err, log.Stack(2))
g.doShutdown()
}
}()
run(func(ctx context.Context, atShutdown func()) { run(func(ctx context.Context, atShutdown func()) {
go func() { go func() {
select { select {
func (g *Manager) RunWithShutdownChan(run RunnableWithShutdownChan) { func (g *Manager) RunWithShutdownChan(run RunnableWithShutdownChan) {
g.runningServerWaitGroup.Add(1) g.runningServerWaitGroup.Add(1)
defer g.runningServerWaitGroup.Done() defer g.runningServerWaitGroup.Done()
defer func() {
if err := recover(); err != nil {
log.Critical("PANIC during RunWithShutdownChan: %v\nStacktrace: %s", err, log.Stack(2))
g.doShutdown()
}
}()
run(g.IsShutdown(), func(ctx context.Context, atTerminate func()) { run(g.IsShutdown(), func(ctx context.Context, atTerminate func()) {
g.RunAtTerminate(ctx, atTerminate) g.RunAtTerminate(ctx, atTerminate)
}) })
func (g *Manager) RunWithShutdownContext(run func(context.Context)) { func (g *Manager) RunWithShutdownContext(run func(context.Context)) {
g.runningServerWaitGroup.Add(1) g.runningServerWaitGroup.Add(1)
defer g.runningServerWaitGroup.Done() defer g.runningServerWaitGroup.Done()
defer func() {
if err := recover(); err != nil {
log.Critical("PANIC during RunWithShutdownContext: %v\nStacktrace: %s", err, log.Stack(2))
g.doShutdown()
}
}()
run(g.ShutdownContext()) run(g.ShutdownContext())
} }


func (g *Manager) RunAtTerminate(ctx context.Context, terminate func()) { func (g *Manager) RunAtTerminate(ctx context.Context, terminate func()) {
g.terminateWaitGroup.Add(1) g.terminateWaitGroup.Add(1)
go func() { go func() {
defer g.terminateWaitGroup.Done()
defer func() {
if err := recover(); err != nil {
log.Critical("PANIC during RunAtTerminate: %v\nStacktrace: %s", err, log.Stack(2))
}
}()
select { select {
case <-g.IsTerminate(): case <-g.IsTerminate():
terminate() terminate()
case <-ctx.Done(): case <-ctx.Done():
} }
g.terminateWaitGroup.Done()
}() }()
} }


// RunAtShutdown creates a go-routine to run the provided function at shutdown // RunAtShutdown creates a go-routine to run the provided function at shutdown
func (g *Manager) RunAtShutdown(ctx context.Context, shutdown func()) { func (g *Manager) RunAtShutdown(ctx context.Context, shutdown func()) {
go func() { go func() {
defer func() {
if err := recover(); err != nil {
log.Critical("PANIC during RunAtShutdown: %v\nStacktrace: %s", err, log.Stack(2))
}
}()
select { select {
case <-g.IsShutdown(): case <-g.IsShutdown():
shutdown() shutdown()
// RunAtHammer creates a go-routine to run the provided function at shutdown // RunAtHammer creates a go-routine to run the provided function at shutdown
func (g *Manager) RunAtHammer(ctx context.Context, hammer func()) { func (g *Manager) RunAtHammer(ctx context.Context, hammer func()) {
go func() { go func() {
defer func() {
if err := recover(); err != nil {
log.Critical("PANIC during RunAtHammer: %v\nStacktrace: %s", err, log.Stack(2))
}
}()
select { select {
case <-g.IsHammer(): case <-g.IsHammer():
hammer() hammer()

+ 8
- 0
modules/webhook/deliver.go Datei anzeigen



// Deliver deliver hook task // Deliver deliver hook task
func Deliver(t *models.HookTask) error { func Deliver(t *models.HookTask) error {
defer func() {
err := recover()
if err == nil {
return
}
// There was a panic whilst delivering a hook...
log.Error("PANIC whilst trying to deliver webhook[%d] for repo[%d] to %s Panic: %v\nStacktrace: %s", t.ID, t.RepoID, t.URL, err, log.Stack(2))
}()
t.IsDelivered = true t.IsDelivered = true


var req *http.Request var req *http.Request

+ 8
- 0
services/mirror/mirror.go Datei anzeigen



func syncMirror(repoID string) { func syncMirror(repoID string) {
log.Trace("SyncMirrors [repo_id: %v]", repoID) log.Trace("SyncMirrors [repo_id: %v]", repoID)
defer func() {
err := recover()
if err == nil {
return
}
// There was a panic whilst syncMirrors...
log.Error("PANIC whilst syncMirrors[%s] Panic: %v\nStacktrace: %s", repoID, err, log.Stack(2))
}()
mirrorQueue.Remove(repoID) mirrorQueue.Remove(repoID)


m, err := models.GetMirrorByRepoID(com.StrTo(repoID).MustInt64()) m, err := models.GetMirrorByRepoID(com.StrTo(repoID).MustInt64())

Laden…
Abbrechen
Speichern