safe

package
v2.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 2, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package safe keeps a panic in Studio's background work from taking the whole process down. Go's runtime ends the process on any goroutine's unrecovered panic; embedded in a host (the Dashboard, MDCB), that would take the host down with it, and every edge that depends on it.

A recovered panic is logged with its stack through the logger package (logger.Current, so it shows even where Studio's logger was never set up) and counted (Panics, and aistudio_goroutine_panics_total when metrics are on).

  • Recover, deferred at the top of a goroutine, ends that goroutine quietly instead of the process; RecoverWith also tells its owner.
  • Go starts a one-shot goroutine that does so.
  • Call runs a function in the current goroutine and reports whether it panicked, for per-item work (a handler, one event) whose loop should carry on with the next item.
  • Loop supervises a long-lived loop: it runs the loop again, after a backoff, when it panics.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Call

func Call(name string, fn func()) (panicked bool)

Call runs fn and reports whether it panicked; the panic is recovered and reported under name.

func Go

func Go(name string, fn func())

Go runs fn in a new goroutine; a panic in fn is recovered and reported under name.

func Loop

func Loop(name string, stop <-chan struct{}, fn func(), opts ...LoopOption)

Loop runs fn, a long-lived loop, in the calling goroutine until it returns. When fn panics, Loop recovers, reports it under name, and runs fn again after a backoff (1 s, doubling to 30 s), unless stop is closed first. Because it runs in the caller's goroutine, the caller's own shutdown signalling (defer close(done), a WaitGroup) keeps its meaning: it happens once, when Loop returns.

fn starts from the top after a panic, so whatever it sets up for itself (tickers, local state) is set up again; state it shares with the rest of its type must survive a panic midway, or be reset with AfterPanic.

func Panics

func Panics() uint64

Panics returns how many panics this process has recovered through the package.

func Recover

func Recover(name string)

Recover recovers a panic in the goroutine it is deferred in and reports it under name. It must be deferred directly: defer safe.Recover("relay").

func RecoverWith

func RecoverWith(name string, then func())

RecoverWith is Recover that also calls then after a panic, for a goroutine whose owner must learn that it ended (to end a stream, say). It must be deferred directly: defer safe.RecoverWith("recv", cancel).

Types

type LoopOption

type LoopOption func(*loopConfig)

LoopOption tunes Loop.

func AfterPanic

func AfterPanic(fn func()) LoopOption

AfterPanic has Loop call fn after each recovered panic, before it waits to run the loop again: to drop state the panic may have left half done (a connection, a lease the replica can no longer vouch for). A panic in fn is recovered too.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL