36 lines
1.2 KiB
Go
36 lines
1.2 KiB
Go
package inventory
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/jackc/pgx/v5/pgconn"
|
|
)
|
|
|
|
// Unreachable says whether an error means the store could not be asked right now, rather than
|
|
// that it answered no.
|
|
//
|
|
// The difference decides whether something worth keeping is kept or lost. The store is recreated
|
|
// when the foundation is adopted (ADR 0078), and for those seconds every write fails with "the
|
|
// database system is starting up" or a refused connection; a caller that treats that like a
|
|
// refusal throws away what it was writing — a node's report of the apply that caused the restart
|
|
// was lost exactly so, and the mesh never heard from the node again (novox/hq issue 082).
|
|
//
|
|
// Unreachable is a connection that failed, and the server classes that mean "not now": 08
|
|
// (connection exception) and 57 (operator intervention — starting up, shutting down, admin
|
|
// shutdown, cannot connect now). Everything else is an answer, and asking again gets the same one.
|
|
func Unreachable(err error) bool {
|
|
if err == nil {
|
|
return false
|
|
}
|
|
var connect *pgconn.ConnectError
|
|
if errors.As(err, &connect) {
|
|
return true
|
|
}
|
|
var pg *pgconn.PgError
|
|
if errors.As(err, &pg) {
|
|
return strings.HasPrefix(pg.Code, "08") || strings.HasPrefix(pg.Code, "57")
|
|
}
|
|
return false
|
|
}
|