Documentation
¶
Overview ¶
Package progress defines the strategy-wide, machine-readable execution progress contract. It deliberately contains copy counters that native operations leave empty so copy-and-swap can implement the same contract.
Index ¶
- Constants
- type Clock
- type Detail
- type Operation
- type Phase
- type Snapshot
- type Tracker
- func (t *Tracker) Finish(err error)
- func (t *Tracker) Now() time.Time
- func (t *Tracker) Progress(ctx context.Context) (Snapshot, error)
- func (t *Tracker) SetAttempt(attempt int)
- func (t *Tracker) SetConcurrentBuild(session dbconn.RowQuerier, pid uint32)
- func (t *Tracker) Start(total int, operation Operation)
- func (t *Tracker) StartStep(step int, operation Operation)
- func (t *Tracker) StopConcurrentBuild()
- type WallClock
- type Work
Constants ¶
const FormatVersion = 1
FormatVersion identifies the snapshot contract. A consumer must reject a snapshot whose format_version it does not recognize rather than guess at field semantics. Adding a phase or operation value is a contract change and bumps this version, even when no field is added or renamed.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Detail ¶
type Detail struct {
Operation Operation `json:"operation,omitempty"`
ServerPhase string `json:"server_phase,omitempty"`
Active bool `json:"active"`
Attempt int `json:"attempt,omitempty"`
Work *Work `json:"work,omitempty"`
}
Detail describes the operation currently executing.
type Operation ¶
type Operation string
Operation is the current operation's execution class.
const ( // OperationAdmitting is the pre-execution window in which a sequence's // steps are still being validated; no statement has run yet. OperationAdmitting Operation = "admitting" // OperationOptimistic is one bounded direct native attempt. OperationOptimistic Operation = "optimistic" // OperationBrief is a brief transactional sequence step. OperationBrief Operation = "brief" // OperationValidate is a constraint-validation scan. OperationValidate Operation = "validate-constraint" // OperationConcurrentIndex is a concurrent index build. OperationConcurrentIndex Operation = "concurrent-index-build" )
type Phase ¶
type Phase string
Phase is the overall execution phase.
const ( // PhasePending means execution has not started. PhasePending Phase = "pending" // PhaseRunning means execution is active. PhaseRunning Phase = "running" // PhaseFinished means execution completed successfully. PhaseFinished Phase = "finished" // PhaseFailed means execution reached a terminal failure. PhaseFailed Phase = "failed" )
type Snapshot ¶
type Snapshot struct {
FormatVersion int `json:"format_version"`
Phase Phase `json:"phase"`
Step int `json:"step,omitempty"`
TotalSteps int `json:"total_steps,omitempty"`
Elapsed time.Duration `json:"elapsed_ns"`
StepElapsed time.Duration `json:"step_elapsed_ns"`
Detail Detail `json:"detail"`
}
Snapshot is one immutable progress observation. For a terminal phase the elapsed values are frozen at the instant Finish recorded, so a late poll reports the execution's duration, not the observation's age.
type Tracker ¶
type Tracker struct {
// contains filtered or unexported fields
}
Tracker is a concurrency-safe progress source. The caller owns it; it has no goroutines. Progress performs the one read needed for an active index build, making polling lifetime identical to the caller's context.
Two locks split the tracker's concerns: mu guards the state fields and is held only for memory access, so the executor's own updates never wait for a database read; pollMu serializes observers, so the reserved session — a single pgx connection that is not safe for concurrent use — only ever carries one progress query at a time.
func NewTracker ¶
NewTracker constructs an idle tracker using clock.
func (*Tracker) Finish ¶
Finish records a terminal execution outcome and the instant it happened; elapsed values in later snapshots freeze at that instant.
func (*Tracker) Progress ¶
Progress returns a snapshot and, for an active concurrent index build, queries PostgreSQL's progress view by the executor-owned backend PID. On a query error the snapshot still carries the last-known tracker state. The state lock is released before the query, so concurrent pollers serialize only against each other (and StopConcurrentBuild), never against the executor's own state updates.
func (*Tracker) SetAttempt ¶
SetAttempt records the current bounded retry attempt.
func (*Tracker) SetConcurrentBuild ¶
func (t *Tracker) SetConcurrentBuild(session dbconn.RowQuerier, pid uint32)
SetConcurrentBuild enables on-demand server progress for pid. The executor supplies its reserved verdict session so polling cannot starve behind the build session even when the pool has only two connections.
func (*Tracker) Start ¶
Start records the beginning of an execution. It resets all per-execution state, so a reused tracker never leaks a prior run's step, terminal time, or session into the new run's snapshots.
func (*Tracker) StartStep ¶
StartStep advances a sequence to a 1-based step and drops any build session from a prior step, so a later step can never poll a stale build.
func (*Tracker) StopConcurrentBuild ¶
func (t *Tracker) StopConcurrentBuild()
StopConcurrentBuild waits for an in-flight observation and releases the reserved session back to the executor before its catalog verdict.
type Work ¶
type Work struct {
RowsCopied uint64 `json:"rows_copied"`
RowsTotal uint64 `json:"rows_total"`
BytesCopied uint64 `json:"bytes_copied"`
BytesTotal uint64 `json:"bytes_total"`
BlocksDone uint64 `json:"blocks_done"`
BlocksTotal uint64 `json:"blocks_total"`
TuplesDone uint64 `json:"tuples_done"`
TuplesTotal uint64 `json:"tuples_total"`
}
Work reports server-observed work. It is present only when the server published a progress row, and then every counter marshals explicitly — a fresh build reports honest zeros, never an empty object a consumer must guess at. Rows and bytes are reserved for copy-and-swap; native operations do not fabricate them.