Documentation
¶
Overview ¶
Package safe spawns detached (fire-and-forget) goroutines with panic isolation.
A panic in a bare `go func(){…}()` that nobody recovers propagates to the top of that goroutine and crashes the WHOLE process — killing every live connection in a co-located deployment, not just the failing task. The request path already guards against this (the handler's ServeHTTP recover), but every OTHER background goroutine — health/resolve loops, the ingress/gateway reconcile + status writers, per-connection access-socket streamers, reload-drain timers — was unguarded, so a single nil-deref in any of them took the node down.
safe.Go / safe.Recover contain such a panic: recover it, count it, log it (with the goroutine's name, the panic value, and a stack), and DO NOT re-panic — mirroring the handler's background-revalidation guard. Recovery here is a last-resort safety net, not a substitute for handling errors on the normal path.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Go ¶
Go runs fn in a new goroutine guarded by Recover, so a panic in fn is contained (recovered + counted + logged) instead of crashing the process. name labels the goroutine for the recovery log; log may be nil.
func LogRecovered ¶
LogRecovered counts and logs a panic value the CALLER already recovered inline. Use it when a goroutine body needs to call recover() itself (e.g. to also update its own state on a panic, like bumping a failure counter) rather than delegating the whole recovery to Recover: pass the non-nil value from `recover()` here so the count and the log line stay identical to Go/Recover. v must be non-nil (the caller checks `recover() != nil`).
func Recover ¶
Recover is the deferred panic guard for a detached goroutine: defer it as the FIRST statement of a `go func(){…}` body so it runs LAST on unwind and contains any panic. name identifies the goroutine in the log line; log may be nil (the panic is still recovered and counted, just not logged). It never re-panics.
Use this directly when a goroutine body must run other defers (e.g. wg.Done, a slot release) alongside the guard; otherwise prefer Go, which wraps the whole body.
Types ¶
This section is empty.