Documentation
¶
Overview ¶
Package runtime encapsulates the unified IPC bootstrap sequence that every Pando entrypoint must follow: derive ports, try the lock, open RW or RO DB, and wire services accordingly.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewPrimaryBus ¶ added in v0.710.6
NewPrimaryBus creates the Bus a primary serves on, with the ipc.ping liveness handler registered, so a freshly started secondary can tell a healthy primary apart from a suspended one (see killStalePrimary). Used by Bootstrap and by failover promotion, so a promoted primary answers the probe exactly like one that started as primary.
Types ¶
type BootstrapResult ¶
type BootstrapResult struct {
Role Role
// Querier is the db.Querier callers should use for all DB operations.
// Primary: direct db.New(SQLDB). Secondary: a DBProxy that forwards writes
// to the primary via ZMQ RPC and serves reads from the local RO connection.
Querier db.Querier
// SQLDB is the underlying *sql.DB. Primary holds a RW pool with WAL
// pragmas applied and migrations run. Secondary holds a 1-connection RW
// pool with a short busy_timeout (db.ConnectRWSecondary); on failover
// promotion that same pool is upgraded in place (db.PromoteToPrimaryPool).
SQLDB *sql.DB
// Bus is non-nil only on the primary instance.
Bus *ipc.Bus
// IPCClient is non-nil only on the secondary instance.
IPCClient *ipc.Client
InstanceID string
PubPort int
RPCPort int
// LockFile is the open flock file held by the primary, nil on secondary.
LockFile *os.File
// Watcher monitors primary liveness. Non-nil on a primary and on a
// secondary with a working IPC client. Automatic failover is enabled by
// default (failover.DefaultConfig); Watcher.SetEnabled(false) turns it off.
// A secondary watcher never takes the IPC lock until a promotion callback
// is registered with Watcher.SetPromoteCallback.
Watcher *failover.Watcher
// Cleanup releases all resources acquired during Bootstrap. On a primary
// it follows the ordered handover: release the lock, announce
// instance.shutdown, close the bus, then close the DB. It is idempotent;
// the caller should call it on shutdown (typically deferred).
Cleanup func()
// contains filtered or unexported fields
}
BootstrapResult carries everything a caller needs after Bootstrap returns. Call Cleanup() on shutdown to release resources in correct order.
func Bootstrap ¶
func Bootstrap(ctx context.Context, workdir, instanceID string) (*BootstrapResult, error)
Bootstrap runs the unified startup sequence for the given workdir using DefaultOptions. See BootstrapWithOptions for the full sequence and for entrypoints that need a different stale-primary policy.
func BootstrapWithOptions ¶ added in v0.710.6
func BootstrapWithOptions(ctx context.Context, workdir, instanceID string, opts Options) (*BootstrapResult, error)
BootstrapWithOptions runs the unified startup sequence for the given workdir.
- Derive deterministic PUB/RPC ports from the path.
- Attempt to acquire the exclusive IPC lock.
- Primary: open RW DB (with migrations), create Bus, create direct Querier.
- Secondary: open RO DB, create IPC Client, create DBProxy Querier.
On lock error the function continues as primary so the caller does not lose functionality — consistent with the existing root.go behaviour.
opts controls the stale-primary probe timeout and whether an unresponsive primary is killed (see Options). A zero opts.ProbeTimeout falls back to stalePrimaryProbeTimeout.
func (*BootstrapResult) ReleaseLock ¶ added in v0.710.6
func (r *BootstrapResult) ReleaseLock()
ReleaseLock releases the primary's IPC lock now, ahead of Cleanup, so a shutting-down primary can hand the lock over before it finishes its own (possibly slow) shutdown. Idempotent, and a no-op on a secondary; Cleanup calls it too.
type Options ¶ added in v0.710.6
type Options struct {
// ProbeTimeout bounds how long a freshly started secondary waits for the
// existing primary to answer ipc.ping before treating it as unresponsive.
// Zero falls back to stalePrimaryProbeTimeout (10s).
ProbeTimeout time.Duration
// AllowKillStalePrimary, when true, SIGKILLs an unresponsive primary so
// this instance can take over — Bootstrap's long-standing behaviour, and
// correct for a TUI/ACP/serve/desktop/app instance where the previous
// occupant of this workdir is presumed to be another one of the same kind.
//
// When false, an unresponsive primary is left alone: this instance
// continues as a (degraded) secondary instead. Direct-first sqlc writes
// still work as normal (DBProxy always tries them locally before
// forwarding), but every remembrances write (which always proxies, never
// direct) fails loudly once its forward times out, because there is
// nobody alive to answer it. Intended for short-lived, low-trust
// entrypoints (P2's ephemeral mcp-server) that must never kill a user's
// long-running TUI/desktop/serve instance just because it is slow, under a
// debugger, or SIGSTOPped to answer one probe.
AllowKillStalePrimary bool
}
Options customizes Bootstrap's stale-primary handling. Use DefaultOptions (what Bootstrap itself uses) unless an entrypoint needs a different policy — see BootstrapWithOptions.
func DefaultOptions ¶ added in v0.710.6
func DefaultOptions() Options
DefaultOptions returns Bootstrap's long-standing policy: the 10s probe timeout (stalePrimaryProbeTimeout) and permission to kill an unresponsive primary.