Documentation
¶
Index ¶
- Constants
- func BatchSubject(batchID string) failure.Subject
- func IsBatchStateHalted(s BatchState) bool
- func IsRequestStateHalted(s RequestState) bool
- func IsRequestStateTerminal(s RequestState) bool
- func QueueSubject(queue string) failure.Subject
- func RequestSubject(requestID string) failure.Subject
- type Author
- type Batch
- type BatchChanges
- type BatchDependent
- type BatchID
- type BatchOutcome
- type BatchState
- type Build
- type BuildID
- type BuildMetadata
- type BuildStatus
- type CancelRequest
- type CandidatePath
- type ChangeDetails
- type ChangeInfo
- type ChangeOutcome
- type ChangeRecord
- type ChangedFile
- type Conflict
- type ConflictType
- type DependencyAssumption
- type GetRequestHistoryByChangeURIRequest
- type GetRequestHistoryByIDRequest
- type GetRequestSummaryByChangeURIRequest
- type GetRequestSummaryByIDRequest
- type LandRequest
- type LandResult
- type ListRequest
- type ListResult
- type MergeResult
- type OutcomeStatus
- type PathAction
- type PathBuild
- type PathDependency
- type PushResult
- type QueueBatchState
- type QueueConfig
- type Request
- type RequestBatch
- type RequestEvent
- type RequestHistory
- type RequestID
- type RequestLog
- type RequestLogType
- type RequestQueueSummary
- type RequestState
- type RequestStatus
- type RequestSummary
- type RequestURI
- type Speculation
- type SpeculationPath
- type SpeculationPathEntry
- type SpeculationPathSet
- type SpeculationPathStatus
Constants ¶
const ( // SubjectTypeBatch identifies a subject by batch ID. SubjectTypeBatch = "batch" // SubjectTypeQueue identifies a subject by queue name. Used where no single // batch is at fault — a failure reading or planning the queue as a whole. SubjectTypeQueue = "queue" // SubjectTypeRequest identifies a subject by request ID. SubjectTypeRequest = "request" )
Subject types name what a failure is about. The queue layer treats the type as opaque; these are SubmitQueue's own vocabulary for it.
Variables ¶
This section is empty.
Functions ¶
func BatchSubject ¶
BatchSubject names a batch as what a failure is about.
func IsBatchStateHalted ¶
func IsBatchStateHalted(s BatchState) bool
IsBatchStateHalted returns true if the batch is either terminal or in the process of being cancelled. Forward-progress controllers (build, buildsignal, speculate, merge) use this to short-circuit work for batches that the user has asked to cancel — even though Cancelling is non-terminal, no further pipeline work should start (cancel will write the terminal state and fan out).
func IsRequestStateHalted ¶
func IsRequestStateHalted(s RequestState) bool
IsRequestStateHalted returns true if the request is either terminal or in the process of being cancelled. Forward-progress controllers (validate, batch, ...) use this to short-circuit work for requests that the user has asked to cancel — even though Cancelling is non-terminal, no further pipeline work should start.
func IsRequestStateTerminal ¶
func IsRequestStateTerminal(s RequestState) bool
IsRequestStateTerminal returns true if the state represents a final, irreversible state (landed, error, or cancelled). RequestStateCancelling is intentionally excluded: cancellation is best-effort and a Cancelling request may still transition to Landed or Error before it reaches Cancelled. Callers that want to gate forward progress (and treat Cancelling as halted) should use IsRequestStateHalted instead.
func QueueSubject ¶
QueueSubject names a queue as what a failure is about. It is the honest subject for work that spans the queue — listing it, planning it — where blaming any one batch would be a guess.
func RequestSubject ¶
RequestSubject names a request as what a failure is about.
Types ¶
type Author ¶
type Author struct {
// Name is the display name of the author.
Name string `json:"name"`
// Email is the email address of the author.
Email string `json:"email"`
}
Author represents the author of a change.
type Batch ¶
type Batch struct {
// ID is the globally unique identifier for the batch. Format: "<queue>/batch/<counter_value>".
ID string
// Queue is the name of the queue processing the land request. Queue name is defined in the configuration and should be unique within the system.
Queue string
// Contains is a list of land request IDs that are part of this batch.
// Request IDs will always be part of the same queue.
//
// For e.g. - [queueA/1, queueA/2, queueA/3].
//
Contains []string
// Dependencies is a list of other batch IDs that this batch depends on.
// Dependencies will always be part of the same queue. This way batches form a directed acyclic graph (DAG).
// If a batch A depends on batch B directly, it means that some request in batch A has overlapping changed targets with
// some another request in batch B. The Dependencies list contains all the transitive closure of all the dependencies, both direct and indirect.
// The order is not specified. Only active batches are considered for dependencies, i.e. if the batch is in a terminal state, it does not need to be included.
// Because batch states are eventually consistent, dependent batches identified at the time of batch creation may move to terminal states. The interpretation logic
// should reconcile batch states separately (i.e. ignore them for processing).
//
//This field is ok to be updated whether the state of the dependency graph changes. Update should use Version property for optimistic locking.
//
// Example: consider batches - queueA/batch/1, queueA/batch/2, queueA/batch/3
// such that - queueA/batch/2 and queueA/batch/3 have overlapping targets with requests in queueA/batch/1, but queueA/batch/2 and queueA/batch/3 do not have overlapping targets with each other.
//
// In this case, the Dependencies field for -
// - queueA/batch/1 will be empty
// - queueA/batch/2 will contain queueA/batch/1
// - queueA/batch/3 will contain queueA/batch/1
Dependencies []string
// The state of the batch lifecycle this batch is in. Updateable field with Version for optimistic locking.
State BatchState
// Version is the version of the object. It is used for optimistic locking.
// Versioning starts at 1 and is incremented for each change to the object.
Version int32
}
Batch represents a group of requests to land (merge into target branch of the source control repository).
func BatchFromBytes ¶
BatchFromBytes deserializes a Batch from JSON bytes.
type BatchChanges ¶
type BatchChanges struct {
// BatchID is the batch being scored. Format: "<queue>/batch/<counter_value>".
BatchID string
// Queue is the queue the batch belongs to.
Queue string
// Changes is every change (URI + provider-supplied details) across all requests
// in the batch. Order is unspecified.
Changes []ChangeInfo
}
BatchChanges is the normalized, batch-level view of all changes in a batch: one ChangeInfo per claimed URI, aggregated across every request the batch contains. It is produced by the shared changeset resolver (Resolver.DetailedForBatch) and consumed by a Scorer. A Batch references only request IDs, so the resolver resolves each request's change records and flattens their details into Changes — giving the scorer the whole batch's change facts in one value without coupling it to storage.
func (BatchChanges) TotalFiles ¶
func (b BatchChanges) TotalFiles() int
TotalFiles returns the total number of files touched across every change in the batch.
func (BatchChanges) TotalLinesChanged ¶
func (b BatchChanges) TotalLinesChanged() int
TotalLinesChanged returns the total number of lines touched across every change in the batch.
type BatchDependent ¶
type BatchDependent struct {
// BatchID is the globally unique identifier of the upstream batch. Format: "<queue>/batch/<counter_value>".
BatchID string
// Dependents is a list of batch IDs that depend on this batch (i.e. batches whose Dependencies list contains BatchID).
// Updated as new batches are created that conflict with this batch. Uses Version for optimistic locking on updates.
Dependents []string
// Version is the version of the object. It is used for optimistic locking.
// Versioning starts at 1 and is incremented for each change to the object.
Version int32
}
BatchDependent is the reverse index of Batch.Dependencies. While Batch.Dependencies lists the batches a batch depends on (upstream), BatchDependent maps a batch to the batches that depend on it (downstream). This enables efficient fan-out notifications when a batch completes or fails — rather than scanning all batches to find which ones reference a given dependency, the system can look up dependents directly.
Example: consider batches queueA/batch/1, queueA/batch/2, queueA/batch/3 where batch/2 and batch/3 both depend on batch/1 (i.e. batch/1 is in their Dependencies list).
The BatchDependent records would be:
- BatchID=queueA/batch/1 → Dependents=[queueA/batch/2, queueA/batch/3]
- BatchID=queueA/batch/2 → Dependents=[] (nothing depends on it)
- BatchID=queueA/batch/3 → Dependents=[] (nothing depends on it)
type BatchID ¶
type BatchID struct {
// ID is the globally unique identifier for the batch.
ID string `json:"id"`
// Queue is the name of the queue processing the batch. Empty on payloads written before the field existed.
Queue string `json:"queue"`
}
BatchID is a lightweight entity for publishing and consuming just the batch identifier via the queue.
func BatchIDFromBytes ¶
BatchIDFromBytes deserializes a BatchID from JSON bytes.
type BatchOutcome ¶
type BatchOutcome struct {
// BatchID is the input batch this outcome corresponds to.
BatchID string
// Outcomes is one entry per change in the batch, in apply order.
Outcomes []ChangeOutcome
}
BatchOutcome groups the per-change outcomes for a single pushed batch, so a merge-train push (several batches in one call) stays correlatable back to the batch each change belonged to. There is no per-batch status: a push is all-or-nothing across the whole call, so a per-batch pass/fail would be uniformly redundant.
type BatchState ¶
type BatchState string
BatchState defines the possible states of a batch.
const ( // BatchStateUnknown is the unreachable state. It is set by default when the structure is initialized. It should never be seen in the system. BatchStateUnknown BatchState = "" // BatchStateCreating indicates that the batch has been persisted but its dependency reverse indexes may not yet be fully initialized. // A Creating batch is not eligible to be referenced as a dependency. BatchStateCreating BatchState = "creating" // BatchStateCreated indicates that the batch and its dependency reverse indexes are fully initialized and ready for processing. BatchStateCreated BatchState = "created" // BatchStateSpeculating is the state of a batch that is undergoing speculative execution. BatchStateSpeculating BatchState = "speculating" // BatchStateMerging is the state of a batch that is being merged after speculative execution. BatchStateMerging BatchState = "merging" // BatchStateSucceeded is the terminal state of a batch that has been successfully landed. BatchStateSucceeded BatchState = "succeeded" // BatchStateFailed is the terminal state of a batch that has failed. BatchStateFailed BatchState = "failed" // BatchStateCancelling is the non-terminal intent state set when a cancel has been requested but the // batch has not yet been transitioned to BatchStateCancelled. A batch in this state may still reach // BatchStateSucceeded or BatchStateFailed if a concurrent merge wins the race (e.g. the push had // already completed before the cancel CAS observed the batch); those terminal states prevail. // Forward-progress controllers must treat this state as halted (no new work). The speculate // controller owns the transition to the terminal BatchStateCancelled and the downstream fan-out // (cancelling in-flight builds, respeculating dependents, publishing to conclude). BatchStateCancelling BatchState = "cancelling" // BatchStateCancelled is the terminal state of a batch that was cancelled before completion. BatchStateCancelled BatchState = "cancelled" )
func ActiveBatchStates ¶
func ActiveBatchStates() []BatchState
ActiveBatchStates returns batch states eligible for active pipeline and cancellation lookups. Creating is excluded because its reverse-index structure may still be incomplete.
func AllBatchStates ¶
func AllBatchStates() []BatchState
AllBatchStates returns every named batch state, in lifecycle order. BatchStateUnknown is excluded: it is the zero-value sentinel, not a state a batch can occupy.
func DependencyBatchStates ¶
func DependencyBatchStates() []BatchState
DependencyBatchStates returns the batch states that make an in-flight batch eligible to be a dependency of a newly created batch. When a batch is created, the conflict analyzer picks the existing batches it conflicts with as its dependencies; the new batch then speculates on top of them — it "bases" its speculative changes on the changes those batches are expected to land, so it must serialize behind them in the speculation graph.
Only batches still expected to land qualify. BatchStateCancelling is excluded (unlike ActiveBatchStates): a cancelling batch may never land, so basing new speculation on its changes would build on top of changes that can disappear.
func (BatchState) IsCancellable ¶
func (s BatchState) IsCancellable() bool
IsCancellable returns true if cancellation should transition or republish a batch in this state. New non-terminal states are cancellable by default unless explicitly excluded above.
func (BatchState) IsTerminal ¶
func (s BatchState) IsTerminal() bool
IsTerminal returns true if the batch state is a terminal state. Terminal states are states from which no further transitions are possible. BatchStateCancelling is intentionally excluded: cancellation is best-effort and a Cancelling batch may still transition to BatchStateSucceeded or BatchStateFailed before it reaches BatchStateCancelled. Callers that want to gate forward progress (and treat Cancelling as halted) should use IsBatchStateHalted instead.
type Build ¶
type Build struct {
// ID is the identifier minted by the queue's build runner when the build
// is triggered; this is the primary storage key.
ID string
// BatchID is the batch for which this build is scheduled.
BatchID string
// PathID is the speculation path this build verifies, as carried by
// SpeculationPathEntry.ID.
PathID string
// Attempt is which build attempt for that path this is, starting at 1.
// A path may be built more than once, so ID names the run while
// (PathID, Attempt) names the slot it occupies.
Attempt int
// Status represents the state of the build lifecycle this build is in.
Status BuildStatus
}
Build represents a build scheduled for a batch along a specific speculation path. All fields except the Status are immutable after creation.
It is keyed by the runner's build ID, which is the identifier every stage downstream of the trigger already holds: a poll, a webhook, and a runner-side log line all name a build, none of them names a speculation path. The path coordinates ride along on the record so those stages never have to understand speculation to do their job.
func BuildFromBytes ¶
BuildFromBytes deserializes a Build from JSON bytes.
type BuildID ¶
type BuildID struct {
// ID is the globally unique identifier for the build.
ID string `json:"id"`
// Queue is the name of the queue processing the batch this build verifies. Empty on payloads written before the field existed.
Queue string `json:"queue"`
}
BuildID is a lightweight entity for publishing and consuming just the build identifier via the queue.
func BuildIDFromBytes ¶
BuildIDFromBytes deserializes a BuildID from JSON bytes.
type BuildMetadata ¶
BuildMetadata carries provider-defined free-form metadata about a build (e.g. build URL, duration, commit SHA). Keys and values are implementation-defined; callers should not assume any particular schema.
type BuildStatus ¶
type BuildStatus string
BuildStatus defines the possible states of a build. The set is intentionally narrow: every supported build provider must be able to map its native lifecycle into one of these values without leaking provider-specific stages.
const ( // BuildStatusUnknown is the unreachable zero value, set by default when // the structure is initialized. It should never be seen in the system. BuildStatusUnknown BuildStatus = "" // BuildStatusAccepted indicates the build has been accepted for // execution. BuildStatusAccepted BuildStatus = "accepted" // BuildStatusRunning indicates the build is currently executing. BuildStatusRunning BuildStatus = "running" // BuildStatusSucceeded indicates the build completed successfully. // This is a terminal state. BuildStatusSucceeded BuildStatus = "succeeded" // BuildStatusFailed indicates the build did not complete successfully. // This is a terminal state. BuildStatusFailed BuildStatus = "failed" // BuildStatusCancelled indicates the build was cancelled. // This is a terminal state. BuildStatusCancelled BuildStatus = "cancelled" )
func (BuildStatus) IsTerminal ¶
func (s BuildStatus) IsTerminal() bool
IsTerminal returns true if the status represents a final state (Succeeded, Failed, or Cancelled).
type CancelRequest ¶
type CancelRequest struct {
// ID is the globally unique identifier of the request to cancel. Format: "<queue>/<counter_value>".
ID string `json:"id"`
// Queue is the name of the queue processing the request to cancel. Empty on payloads written before the field existed.
Queue string `json:"queue"`
// Reason is an optional free-form explanation of why the cancellation was requested.
Reason string `json:"reason"`
}
CancelRequest represents a cancellation request sent over the queue from the gateway to the orchestrator. It identifies the request to cancel by its ID and carries an optional human-readable reason for observability.
func CancelRequestFromBytes ¶
func CancelRequestFromBytes(data []byte) (CancelRequest, error)
CancelRequestFromBytes deserializes a CancelRequest from JSON bytes.
func (CancelRequest) ToBytes ¶
func (r CancelRequest) ToBytes() ([]byte, error)
ToBytes serializes the CancelRequest to JSON bytes for queue message payload.
type CandidatePath ¶
type CandidatePath struct {
// Path is the candidate: a head plus one assumption per dependency.
Path SpeculationPath
// RankingScore is the score the Generator ranked this candidate by. Higher
// sorts first within the Generator's own ranking. Consumers take candidates
// in iterator order and do not interpret the value. It is meaningful only
// within the run that produced it, which is why it is never stored.
RankingScore float64
}
CandidatePath is a path paired with the transient ranking score assigned to it within a single speculation run. The ranking score orders candidates for that run only and is never stored — rankings go stale across runs.
type ChangeDetails ¶
type ChangeDetails struct {
// Author is the author of the change.
Author Author `json:"author"`
// ChangedFiles is the list of files modified in this change. Order is unspecified.
ChangedFiles []ChangedFile `json:"changed_files,omitempty"`
}
ChangeDetails holds the provider-supplied facts about a single change (author, modified files, line counts). It carries no identity — the owning URI lives on ChangeInfo (provider correlation) and ChangeRecord (persisted claim).
func (ChangeDetails) FileCount ¶
func (d ChangeDetails) FileCount() int
FileCount returns the number of files touched in the change.
func (ChangeDetails) TotalLinesChanged ¶
func (d ChangeDetails) TotalLinesChanged() int
TotalLinesChanged returns the total number of lines touched across all files in the change.
type ChangeInfo ¶
type ChangeInfo struct {
// URI is the full change URI for correlation with the input request
// (e.g., "github://github.example.com/uber/repo/pull/98/c3a4d5e6f7890123456789abcdef0123456789ab").
URI string `json:"uri"`
// Details is the provider-supplied facts for this URI.
Details ChangeDetails `json:"details"`
}
ChangeInfo maps a change URI to its details. It is the change provider's return type: for a Change with multiple URIs (e.g. a stacked PR set), the provider returns one ChangeInfo per URI so callers can correlate results to inputs by URI.
type ChangeOutcome ¶
type ChangeOutcome struct {
// Change is the input change this outcome corresponds to.
Change change.Change
// Status describes whether the change produced commits or was already
// present on the target branch.
Status OutcomeStatus
// CommitSHAs lists the commits this change produced on the target
// branch, in apply order. A single Change may produce multiple commits
// (e.g. a stack of PRs). Empty when Status is OutcomeStatusAlreadyExisted.
CommitSHAs []string
}
ChangeOutcome describes what happened to a single Change inside a push.
type ChangeRecord ¶
type ChangeRecord struct {
// URI identifies the change (RFC 3986). Same scheme/format as change.Change.URIs.
// Example: "github://github.example.com/uber/submitqueue/pull/123/c3a4d5e6f7890123456789abcdef0123456789ab".
URI string `json:"uri"`
// RequestID is the owning land request that claimed this URI.
// Format matches entity.Request.ID: "<queue>/<counter_value>".
//
// RequestID participates in the change-store primary key so that concurrent claims
// by different requests on the same URI coexist as distinct rows. Same-request
// retries collide on the PK and are absorbed idempotently; different-request
// collisions surface as additional rows that callers detect via GetByURI.
RequestID string `json:"request_id"`
// Queue is the queue the owning request belongs to. It is the leading column of
// the change-store primary key, so queue-scoped duplicate checks become PK-prefix
// scans and the table is shardable by queue.
Queue string `json:"queue"`
// Details holds the provider-supplied facts about the change (author, changed
// files, line counts). It is captured at claim time (the validate controller, after
// fetching from the change provider) and written once with the record — records are
// immutable, so Details is never updated after Create.
Details ChangeDetails `json:"details"`
// CreatedAt is the Unix milliseconds timestamp when this record was created.
CreatedAt int64 `json:"created_at"`
// UpdatedAt is the Unix milliseconds timestamp when this record was created. Records
// are immutable, so it always equals CreatedAt; retained for schema symmetry.
UpdatedAt int64 `json:"updated_at"`
// Version is the record version. Records are immutable, so it is always 1; retained
// for schema symmetry with the other stores.
Version int32 `json:"version"`
}
ChangeRecord represents a single URI's claim by a request, persisted in the change store. The whole record is immutable: the (Queue, URI, RequestID) triple is its identity and the Details (author, changed files, line counts) are captured once at claim time from the change provider. There is no update path.
type ChangedFile ¶
type ChangedFile struct {
// Path is the file path relative to the repository root.
Path string `json:"path"`
// LinesAdded is the number of lines added in this file.
LinesAdded int `json:"lines_added"`
// LinesDeleted is the number of lines deleted in this file.
LinesDeleted int `json:"lines_deleted"`
// LinesModified is the number of lines modified in this file. Some providers
// (e.g. GitHub) report only additions and deletions and leave this zero.
LinesModified int `json:"lines_modified"`
}
ChangedFile represents a single file modification in a change.
func (ChangedFile) TotalLines ¶
func (f ChangedFile) TotalLines() int
TotalLines returns the total number of lines touched in this file.
type Conflict ¶
type Conflict struct {
// BatchID is the ID of the in-flight batch that conflicts with the
// analyzed batch.
BatchID string
// Type classifies the conflict. A single (analyzed, in-flight) pair may
// be reported with multiple Conflict entries when different conflict
// types apply.
Type ConflictType
}
Conflict reports a single conflict between an analyzed batch and one of the in-flight batches.
type ConflictType ¶
type ConflictType string
ConflictType classifies why two batches are considered to conflict. New values may be added as more sophisticated analyzers are introduced.
const ( // ConflictTypeUnknown is the unreachable zero value, set by default when // the structure is initialized. It should never be seen in the system. ConflictTypeUnknown ConflictType = "" // ConflictTypeConservative means the analyzer treated the batches as // conflicting because it could not prove otherwise, without identifying a // specific reason. Used by conservative analyzers that serialize // everything by default. ConflictTypeConservative ConflictType = "conservative" // ConflictTypeTargetOverlap means the two batches modify one or more of // the same build targets and may therefore interfere with each other. ConflictTypeTargetOverlap ConflictType = "target_overlap" )
type DependencyAssumption ¶
type DependencyAssumption string
DependencyAssumption is what a path assumes about one dependency's outcome.
const ( // DependencyAssumptionUnknown is the zero-value sentinel; it is never a // valid assumption. DependencyAssumptionUnknown DependencyAssumption = "" // DependencyAssumptionSucceeds assumes the dependency succeeds: the head is // built on top of it, and the path is refuted if it does not. DependencyAssumptionSucceeds DependencyAssumption = "succeeds" // DependencyAssumptionFails assumes the dependency does not succeed — // whether it fails or is cancelled. The head is built without it, and the // path is refuted if it succeeds after all. DependencyAssumptionFails DependencyAssumption = "fails" )
type GetRequestHistoryByChangeURIRequest ¶
type GetRequestHistoryByChangeURIRequest struct {
// ChangeURI is the exact change URI supplied in a Land request.
ChangeURI string
// Queue is the name of the queue to search. It scopes the lookup: a change URI
// landed into several queues matches separately in each.
Queue string
}
GetRequestHistoryByChangeURIRequest identifies retained histories by an exact pinned change URI.
type GetRequestHistoryByIDRequest ¶
type GetRequestHistoryByIDRequest struct {
// ID is the globally unique identifier of the request.
ID string
// Queue is the name of the queue processing the request. It scopes the lookup:
// a request is only resolvable within its own queue.
Queue string
}
GetRequestHistoryByIDRequest identifies one retained request history by request ID.
type GetRequestSummaryByChangeURIRequest ¶
type GetRequestSummaryByChangeURIRequest struct {
// ChangeURI is the exact change URI supplied in a Land request.
ChangeURI string
// Queue is the name of the queue to search. It scopes the lookup: a change URI
// landed into several queues matches separately in each.
Queue string
}
GetRequestSummaryByChangeURIRequest identifies request summaries by an exact pinned change URI.
type GetRequestSummaryByIDRequest ¶
type GetRequestSummaryByIDRequest struct {
// ID is the globally unique identifier of the request. Format: "<queue>/<counter_value>".
ID string
// Queue is the name of the queue processing the request. It scopes the lookup:
// a request is only resolvable within its own queue.
Queue string
}
GetRequestSummaryByIDRequest identifies one request summary by sqid.
type LandRequest ¶
type LandRequest struct {
// ID is the globally unique identifier for the land request. Format: "<queue>/<counter_value>".
ID string `json:"id"`
// Queue is the name of the queue processing the land request.
Queue string `json:"queue"`
// Change is the set of code changes to land.
Change change.Change `json:"change"`
// LandStrategy is the source control integration strategy to use for this
// land operation. It applies to every URI of Change, the same way to each.
LandStrategy mergestrategy.MergeStrategy `json:"land_strategy"`
}
LandRequest represents the gateway-owned fields of a land request sent over the queue to the orchestrator. It contains only the validated inputs and generated ID — the orchestrator is responsible for constructing the full Request entity with state machine fields.
func LandRequestFromBytes ¶
func LandRequestFromBytes(data []byte) (LandRequest, error)
LandRequestFromBytes deserializes a LandRequest from JSON bytes.
func (LandRequest) ToBytes ¶
func (r LandRequest) ToBytes() ([]byte, error)
ToBytes serializes the LandRequest to JSON bytes for queue message payload.
type LandResult ¶
type LandResult struct {
// ID is the globally unique identifier assigned to the accepted land request.
// Format: "<queue>/<counter_value>".
ID string
}
LandResult is the outcome of accepting a land request. It carries the ID the controller assigned to the request so the transport layer can echo it back to the caller.
type ListRequest ¶
type ListRequest struct {
// Queue is the exact queue to query.
Queue string
// ReceivedAtOrAfterMs is the inclusive lower receipt-time bound in Unix milliseconds.
ReceivedAtOrAfterMs int64
// ReceivedBeforeMs is the exclusive upper receipt-time bound in Unix milliseconds.
ReceivedBeforeMs int64
// PageSize is the maximum number of results to return. Zero selects the server default.
PageSize int32
// PageToken is an opaque continuation token from a previous result.
PageToken string
}
ListRequest defines one bounded queue receipt-history query.
type ListResult ¶
type ListResult struct {
// Requests are ordered by receipt time descending, then request ID descending.
Requests []RequestQueueSummary
// NextPageToken is an opaque continuation token. Empty means this is the last page.
NextPageToken string
}
ListResult contains one page of queue receipt history.
type MergeResult ¶
type MergeResult struct {
// Mergeable is true if the request's changes are expected to merge cleanly.
Mergeable bool
// Reason is a human-readable explanation when Mergeable is false.
// Empty when Mergeable is true.
Reason string
}
MergeResult holds the outcome of a mergeability check.
type OutcomeStatus ¶
type OutcomeStatus string
OutcomeStatus describes what happened to a single Change during a push.
const ( // OutcomeStatusUnknown is the unreachable zero value, set by default // when the structure is initialized. It should never be seen in the system. OutcomeStatusUnknown OutcomeStatus = "" // OutcomeStatusCommitted means the change produced one or more commits // on the target branch. CommitSHAs lists those commits in apply order. OutcomeStatusCommitted OutcomeStatus = "committed" // OutcomeStatusAlreadyExisted means the change produced no commits // because every part of it is already present in the target branch // (e.g. it previously landed via another path, or a prior change in // the same push subsumed it). CommitSHAs is empty for this status. // In git terms this is what a `cherry-pick` surfaces as "rebased out". OutcomeStatusAlreadyExisted OutcomeStatus = "already_existed" )
type PathAction ¶
type PathAction string
PathAction is an action proposed on a speculation path. The set is limited to build and cancel; there is no merge or fail action, because a batch's verdict is a controller-owned fact, not a proposed action.
const ( // PathActionUnknown is the zero-value sentinel; it is never a valid action. PathActionUnknown PathAction = "" // PathActionBuild proposes starting (or resurrecting) a build for the path. PathActionBuild PathAction = "build" // PathActionCancel proposes preempting an in-flight path to free build budget. PathActionCancel PathAction = "cancel" )
type PathBuild ¶
type PathBuild struct {
// Queue is the name of the queue the path's head batch belongs to. It is
// unique together with PathID and Attempt.
Queue string
// PathID is the speculation path, as carried by SpeculationPathEntry.ID,
// unique within Queue.
PathID string
// Attempt is which build attempt for that path this is, starting at 1.
Attempt int
// BuildID is the build started for that attempt. Never empty.
BuildID string
}
PathBuild names the build started for one attempt of one speculation path.
It is the reverse of Build's key. A Build is keyed by the identifier the runner minted, which is what every stage watching a build already holds; a caller starting from a path has no way to derive that identifier, so the link is recorded under the coordinates it does hold.
A record is write-once: it is created already naming its build and never changes, so an attempt maps to one build for good — a retried path is a new attempt under a different key. An absent record means no build is recorded for the attempt; it does not promise that none is starting.
type PathDependency ¶
type PathDependency struct {
// Batch is the dependency batch ID.
Batch string
// Assumption is what the path assumes about that dependency's outcome.
Assumption DependencyAssumption
}
PathDependency is one dependency of a path's head, with what the path assumes about it.
type PushResult ¶
type PushResult struct {
// Batches is one entry per pushed batch, in the same order as the batches
// passed to the push. The slice length equals the input length.
Batches []BatchOutcome
}
PushResult is the outcome of a successful push.
type QueueBatchState ¶
type QueueBatchState struct {
// Queue is the name of the queue the batch belongs to. Queue name is defined in the
// configuration and should be unique within the system.
Queue string
// State is the lifecycle state bucket this record files the batch under. Advisory:
// the batch's authoritative state lives on the Batch entity and may differ transiently.
State BatchState
// BatchID is the globally unique identifier of the batch. Format: "<queue>/batch/<counter_value>".
BatchID string
}
QueueBatchState is a membership record filing one in-queue batch under one lifecycle state bucket of its queue. A record exists for every batch from its creation until it exits the queue — through terminal states, not just while in flight.
The (Queue, State, BatchID) triple is the record's identity; records carry no other data and are never updated in place — a batch changes buckets by a record appearing under the new state and the old record disappearing.
Records are advisory. The authoritative state is the State field of the Batch identified by BatchID; a record may transiently file a batch under a bucket the batch has already left, and a batch may transiently have records in more than one bucket. A batch is never without at least one record while it is in the queue.
type QueueConfig ¶
type QueueConfig struct {
// Name uniquely identifies this queue within the system.
// Referenced by Request.Queue.
Name string `json:"name" yaml:"name"`
}
QueueConfig identifies a single submit queue. It is the registry of valid queue names; the gateway validates that a land request targets a known queue. All behavioral and VCS configuration lives in the extension factory implementations, which are constructed per integrator deployment — the system hands a factory only the queue name. Immutable after creation.
type Request ¶
type Request struct {
// ID is the globally unique identifier for the land request. Format: "<queue>/<counter_value>".
ID string `json:"id"`
// Queue is the name of the queue processing the land request. Queue name is defined in the configuration and should be unique within the system.
Queue string `json:"queue"`
// Change is a number of code changes (such as pull requests) to land into the target branch. Target branch is defined by the queue configuration.
Change change.Change `json:"change"`
// LandStrategy is the source control integration strategy to use for this
// land operation. It applies to every URI of Change, the same way to each.
LandStrategy mergestrategy.MergeStrategy `json:"land_strategy"`
// State is the current state of the land request.
State RequestState `json:"state"`
// Version is the version of the object. It is used for optimistic locking.
// Versioning starts at 1 and is incremented for each change to the object.
Version int32 `json:"version"`
}
Request defines a request to land (merge into target branch of the source control repository) a set of code changes. The object is immutable after creation.
func RequestFromBytes ¶
RequestFromBytes deserializes a Request from JSON bytes.
type RequestBatch ¶
type RequestBatch struct {
// RequestID is the globally unique request identifier.
RequestID string
// BatchID is the globally unique identifier of the batch containing the request.
BatchID string
// Version is the version of the association. Immutable associations start at version 1.
Version int32
}
RequestBatch is an immutable association between a request and one batch attempt containing it.
type RequestEvent ¶
type RequestEvent string
RequestEvent is something that happened to a request while it sat at a status, rather than a status of its own.
Speculation is what the distinction exists for. A batch funds several paths at once and each is built separately, so a build starting or finishing, or one path passing and later being contradicted, says nothing about where the request as a whole is — it is still speculating. Were these statuses, one build succeeding while its siblings ran would report the request as finished, and go on reporting it that way until the batch resolved.
Events are not unique per request: each names one path or build, and a batch may be re-planned many times. They belong in a request's history and are never its current status — which is enforced by the type, since a RequestEvent cannot be assigned to RequestSummary.Status.
const ( // RequestEventUnknown is the unknown sentinel event. It is set by default when the structure is initialized. It should never be seen in the system. RequestEventUnknown RequestEvent = "" // RequestEventBuilding indicates that one build verifying one speculation path of the batch containing the request has started. RequestEventBuilding RequestEvent = "building" // RequestEventBuilt indicates that one build verifying one speculation path of the batch containing the request finished successfully. // A build that fails or is cancelled records nothing. RequestEventBuilt RequestEvent = "built" // RequestEventWaiting indicates that one speculation path of the batch containing the request passed, // leaving the batch nothing of its own to run and waiting on its dependencies to settle. RequestEventWaiting RequestEvent = "waiting" // RequestEventInvalidated indicates that a dependency resolved against the guess made by the passed path // the batch containing the request was waiting on, so that path can no longer carry it. RequestEventInvalidated RequestEvent = "invalidated" )
type RequestHistory ¶
type RequestHistory struct {
// RequestID is the globally unique identifier of the request.
RequestID string
// Events are retained request-log events ordered chronologically.
Events []RequestLog
}
RequestHistory groups retained events for one request.
type RequestID ¶
type RequestID struct {
// ID is the globally unique identifier for the land request.
ID string `json:"id"`
// Queue is the name of the queue processing the land request. Empty on payloads written before the field existed.
Queue string `json:"queue"`
}
RequestID is a lightweight entity for publishing and consuming just the request identifier via the queue.
func RequestIDFromBytes ¶
RequestIDFromBytes deserializes a RequestID from JSON bytes.
type RequestLog ¶
type RequestLog struct {
// RequestID is the ID of the request this log entry belongs to. References entity.Request.ID.
RequestID string `json:"request_id"`
// Queue is the name of the queue processing the request. It is unique together
// with RequestID: a request ID is only unique within its own queue.
Queue string `json:"queue"`
// TimestampMs is the time this log entry was created, in milliseconds since Unix epoch.
TimestampMs int64 `json:"timestamp_ms"`
// Type is what this entry records. An entry read back without one predates the
// field and records a status.
Type RequestLogType `json:"type"`
// Status is the request status this entry records. Set only when Type is RequestLogTypeStatus.
Status RequestStatus `json:"status"`
// Event is the event this entry records. Set only when Type is RequestLogTypeEvent.
Event RequestEvent `json:"event"`
// RequestVersion is the version of the request at the time this log entry was created.
// Zero if the version is not available, and always zero on an event.
RequestVersion int32 `json:"request_version"`
// LastError is the last error message associated with the status at the time of this log entry.
// Empty string if no error.
LastError string `json:"last_error"`
// Metadata is a set of key-value pairs providing additional context for this log entry.
// Empty map if no metadata.
Metadata map[string]string `json:"metadata"`
}
RequestLog is an append-only record that captures a point-in-time snapshot of a request's status for reconciliation purposes. It is stored in a separate database from the request store to support eventual consistency reconciliation.
An entry records either a status or an event, never both, and Type says which. Build the two through NewRequestStatusLog and NewRequestEventLog rather than as a literal, so the unset half stays unset.
func NewRequestEventLog ¶
func NewRequestEventLog(queue string, requestID string, event RequestEvent, metadata map[string]string) RequestLog
NewRequestEventLog creates a RequestLog recording that something happened to a request while it sat at its current status.
It takes no request version because an event is not a state transition: carrying one would let a reader mistake it for a reconcilable status. Arguments otherwise match NewRequestStatusLog.
func NewRequestStatusLog ¶
func NewRequestStatusLog(queue string, requestID string, status RequestStatus, requestVersion int32, lastError string, metadata map[string]string) RequestLog
NewRequestStatusLog creates a RequestLog recording that a request reached a status. TimestampMs is set to the current time. If metadata is nil, it will be initialized as an empty map. queue is the queue processing the request; it scopes requestID, which is only unique within it. requestVersion is the version of the request entity, should only be set if reporting a request state as a status, otherwise it should be 0. lastError is the last error message associated with the status at the time of this log entry, empty string if no error. metadata is a set of key-value pairs providing additional context for this log entry. Not constrained to any specific format or schema, used for display or debugging purposes.
func RequestLogFromBytes ¶
func RequestLogFromBytes(data []byte) (RequestLog, error)
RequestLogFromBytes deserializes a RequestLog from JSON bytes. If metadata is absent from the JSON, it will be initialized as an empty map. An entry without a type predates the field, when every entry recorded a status.
func (RequestLog) ToBytes ¶
func (r RequestLog) ToBytes() ([]byte, error)
ToBytes serializes the RequestLog to JSON bytes for queue message payload.
func (RequestLog) Value ¶
func (r RequestLog) Value() string
Value returns what this entry recorded — its status or its event — as the single string that identifies it for a message ID, a log line, or display.
type RequestLogType ¶
type RequestLogType string
RequestLogType is what a log entry records: the request reaching a status, or an event that happened while it was at one.
const ( // RequestLogTypeStatus is an entry that records a status. Its Status field is // set, and it is a candidate for the request's current status. RequestLogTypeStatus RequestLogType = "status" // RequestLogTypeEvent is an entry that records an event. Its Event field is // set, it carries no request version, and it never becomes a current status. RequestLogTypeEvent RequestLogType = "event" )
type RequestQueueSummary ¶
type RequestQueueSummary struct {
// RequestID is the globally unique request identifier.
RequestID string
// Queue is the queue supplied at receipt.
Queue string
// ChangeURIs are the change URIs supplied at receipt in caller order.
ChangeURIs []string
// ReceivedAtMs is the immutable receipt timestamp in Unix milliseconds.
ReceivedAtMs int64
// Status is the current customer-facing request status.
Status RequestStatus
// Version is copied from the authoritative RequestSummary and guards stale projection writers.
Version int32
// LastError is the error associated with the current status, or empty when absent.
LastError string
// Metadata is display and debugging metadata associated with the current status.
Metadata map[string]string
}
RequestQueueSummary is the queue-ordered projection returned by List.
type RequestState ¶
type RequestState string
RequestState defines the possible states of a land request. They are internal and used to implement a state machine. A separate RequestStatus type is used to track the customer-friendly status of a request.
const ( // RequestStateUnknown is the unreachable state. It is set by default when the structure is initialized. It should never be seen in the system. RequestStateUnknown RequestState = "" // RequestStateStarted is the initial state of a land request. It is confirmed by the system but the processing is not started yet. RequestStateStarted RequestState = "started" // RequestStateValidated indicates that the request has been validated (duplicate check, merge check etc.) successfully. RequestStateValidated RequestState = "validated" // RequestStateBatched indicates that the request has been claimed by the batch controller and enrolled in a // batch. The CAS-write of this state by the batch controller is the serialization point between batch and // cancel: the batch controller transitions Validated → Batched immediately before persisting the new batch, // so any concurrent cancel that has already transitioned the request to Cancelling will lose the CAS and // abandon the batch. From this state forward, the request's terminal outcome is owned by the batch it is // enrolled in (via conclude), not by the cancel controller's request-only fast path. RequestStateBatched RequestState = "batched" // RequestStateProcessing is the state of a land request that is being processed. RequestStateProcessing RequestState = "processing" // RequestStateLanded is the state of a land request that has been successfully processed and landed. This is the final state. RequestStateLanded RequestState = "landed" // RequestStateError is the state of a land request that has encountered an error. This is the final state. RequestStateError RequestState = "error" // RequestStateCancelling is the non-terminal intent state set when the user has requested cancellation but the // request has not yet been transitioned to RequestStateCancelled. A request in this state may still reach // RequestStateLanded or RequestStateError if a concurrent merge or failure wins the race; those terminal // states prevail. Forward-progress controllers must treat this state the same as terminal (i.e. do not start // any new work on the request). RequestStateCancelling RequestState = "cancelling" // RequestStateCancelled is the state of a land request that was cancelled by the user before it could land. This is the final state. RequestStateCancelled RequestState = "cancelled" )
type RequestStatus ¶
type RequestStatus string
RequestStatus is where a request is in the pipeline. It is customer-friendly and can be displayed to the user. It is different from the request state, which is internal and used to implement a state machine. Request statuses can be generally added freely by the system without breaking the state machine. Some statuses correspond to the request state, in which case they should be supplemented with the request state version to be used for reconciliation. Other statuses are purely informational and can be added freely. Every status may be accompanied by a last error message and free-formmetadata in the Request Log. It will only be used for display or debugging purposes.
Exactly one status is a request's current position at any moment. Things that merely happen to a request while it sits at one — a build starting, a build finishing — are not statuses and are not in this vocabulary; they are RequestEvent.
const ( // RequestStatusUnknown is the unknown sentinel status. It is set by default when the structure is initialized. It should never be seen in the system. RequestStatusUnknown RequestStatus = "" // RequestStatusAccepting is the internal status of a persisted Land receipt that has not yet been published to the processing pipeline. // Public read APIs must not expose requests that remain in this status. RequestStatusAccepting RequestStatus = "accepting" // RequestStatusAccepted indicates that the request has been published to the processing pipeline. RequestStatusAccepted RequestStatus = "accepted" // RequestStatusStarted is the initial status of a request. It corresponds to the RequestStateStarted state and typically set by the orchestrator service when the request is received and persisted to the operating database. RequestStatusStarted RequestStatus = "started" // RequestStatusValidating indicates that the request is currently being validated (e.g., duplicate check, merge check, etc.). RequestStatusValidating RequestStatus = "validating" // RequestStatusValidated indicates that the request has been validated (duplicate check, merge check etc.) successfully. It corresponds to the RequestStateValidated state. RequestStatusValidated RequestStatus = "validated" // RequestStatusBatched indicates that the request has been included in a new batch and will be sent to speculation. RequestStatusBatched RequestStatus = "batched" // RequestStatusSpeculating indicates that the batch containing the request is in speculation: // planning, building, or waiting for its dependencies to settle. None of those leaves it able to land. RequestStatusSpeculating RequestStatus = "speculating" // RequestStatusSpeculated indicates that the batch containing the request has finished speculating: // a build passed on a path whose assumptions all held, and the batch has been cleared to merge. RequestStatusSpeculated RequestStatus = "speculated" // RequestStatusLanding indicates that the request is actively being landed (e.g., source control operation is in progress to push the change to the target branch). RequestStatusLanding RequestStatus = "landing" // RequestStatusLanded indicates that the request has been successfully processed and landed. It corresponds to the RequestStateLanded state. RequestStatusLanded RequestStatus = "landed" // RequestStatusError indicates that the request has encountered an error. It corresponds to the RequestStateError state. RequestStatusError RequestStatus = "error" // RequestStatusCancelling indicates that the user has requested cancellation but the request has not yet transitioned // to the RequestStateCancelled state. Cancellation is best-effort: a request that has already been merged or that // races to completion before the cancel propagates through the pipeline may still land. Observers should treat this // as intent only and rely on RequestStatusCancelled (or RequestStatusLanded) for the terminal outcome. Emitted by // the gateway when the Cancel RPC is received. RequestStatusCancelling RequestStatus = "cancelling" // RequestStatusCancelled indicates that the request was cancelled by the user before it could land. It corresponds to the RequestStateCancelled state. RequestStatusCancelled RequestStatus = "cancelled" )
type RequestSummary ¶
type RequestSummary struct {
// RequestID is the globally unique request identifier.
RequestID string
// Queue is the queue supplied at receipt.
Queue string
// ChangeURIs are the change URIs supplied at receipt in caller order.
ChangeURIs []string
// ReceivedAtMs is the immutable receipt timestamp in Unix milliseconds.
ReceivedAtMs int64
// Status is the current customer-facing request status.
Status RequestStatus
// RequestVersion is the orchestrator request version carried by the winning log entry, or zero when unavailable.
RequestVersion int32
// StatusTimestampMs is the timestamp of the winning log entry in Unix milliseconds.
StatusTimestampMs int64
// Version is the optimistic-lock version of this materialized view.
Version int32
// LastError is the error associated with the current status, or empty when absent.
LastError string
// Metadata is display and debugging metadata associated with the current status.
Metadata map[string]string
}
RequestSummary is the gateway-owned materialized current view of a request. RequestID is exposed as sqid by the gateway API.
type RequestURI ¶
type RequestURI struct {
// ChangeURI is the exact canonical URI supplied at receipt.
ChangeURI string
// Queue is the name of the queue the request was received into. It scopes the
// mapping: the same change URI landed into several queues maps separately in each.
Queue string
// ReceivedAtMs is the immutable receipt timestamp in Unix milliseconds.
ReceivedAtMs int64
// RequestID is the globally unique request identifier.
RequestID string
}
RequestURI maps one change URI to one received request.
type Speculation ¶
type Speculation struct {
// Path is the path the action applies to; its ID hashes the head and its
// assumptions.
Path SpeculationPath
// Action is the proposed action (build or cancel).
Action PathAction
}
Speculation is one proposed action on one path. A path left as-is has no Speculation.
type SpeculationPath ¶
type SpeculationPath struct {
// Head is the ID of the batch being built along this path.
Head string
// Dependencies is one entry per dependency of Head, in queue order.
Dependencies []PathDependency
}
SpeculationPath is one set of assumptions about how a batch's dependencies resolve: a head batch plus an assumption about each of its dependencies. Every dependency of the head appears exactly once, in queue order, so the path is self-describing — its full meaning can be read without consulting any external relaxed set or dependency list.
func (SpeculationPath) Base ¶
func (p SpeculationPath) Base() []string
Base returns the path's base — the batches its head is stacked on top of: the IDs of the dependencies the path assumes will succeed, in the path's dependency order.
It is a projection of the path rather than a decision about it — a dependency the path assumes will fail is by definition built without — so every caller that needs the base derives it here rather than re-reading the assumptions itself.
func (SpeculationPath) ID ¶
func (p SpeculationPath) ID() string
ID returns the path's stable identity: a hex-encoded SHA-256 over the head and its dependencies in order. Two paths with the same head and the same ordered assumptions share an ID; any difference in head, dependency, or assumption yields a different ID. The hash is computed on every call and never cached, so a caller that compares IDs repeatedly should keep the result.
type SpeculationPathEntry ¶
type SpeculationPathEntry struct {
// ID is the primary key: the hash of the path's content (head plus its
// assumptions). It always equals Path.ID() — it is materialized here, rather
// than recomputed from Path, because a stored record carries its own key:
// lookups and comparisons read it without rehashing the path.
ID string
// Path is the head plus one assumption per dependency, in queue order.
Path SpeculationPath
// Status is the lifecycle status of the current build attempt.
Status SpeculationPathStatus
// Attempt is the build attempt number for this path, starting at 1. A path
// can be built more than once (e.g. after a prior build is cancelled to free
// budget, or fails and is retried), so ID alone does not identify an
// execution — (ID, Attempt) does. It increments with each new build.
Attempt int
// Version is the version of the object. It is used for optimistic locking.
// Versioning starts at 1 and is incremented for each change to the object.
Version int32
// CreatedAtMs is the creation time in Unix epoch milliseconds.
CreatedAtMs int64
// UpdatedAtMs is the last-update time in Unix epoch milliseconds.
UpdatedAtMs int64
}
SpeculationPathEntry is the stored record of one chosen speculation path, keyed by the hash of its content. It holds no build reference — a build is linked to an attempt by PathBuild, so the path stays what the speculation run decided rather than a mirror of what the build system is doing — and no score (a score is meaningful only within a single speculation run).
type SpeculationPathSet ¶
type SpeculationPathSet struct {
// Queue is the name of the queue the head batch belongs to. It is unique
// together with Head.
Queue string
// Head is the ID of the head batch these paths speculate on, unique within
// Queue. Every path in the set carries this same head.
Head string
// Paths is the head's chosen paths, live and recently finished.
Paths []SpeculationPathEntry
// Version is the version of the object. It is used for optimistic locking.
// Versioning starts at 1 and is incremented for each change to the object.
Version int32
}
SpeculationPathSet is one head's chosen speculation paths under a single version. It holds both live paths and recently finished ones — finished entries linger briefly so that a re-run cannot collide with an old build. Every path in the set shares the same head and assumptions over the same ordered dependency list.
type SpeculationPathStatus ¶
type SpeculationPathStatus string
SpeculationPathStatus is the lifecycle status of one speculation path's current build attempt.
const ( // SpeculationPathStatusUnknown is the zero-value sentinel; it should never be // seen in the system. SpeculationPathStatusUnknown SpeculationPathStatus = "" // SpeculationPathStatusPending indicates the path is funded under the build // budget but its build has not started yet. SpeculationPathStatusPending SpeculationPathStatus = "pending" // SpeculationPathStatusBuilding indicates the path's build is running in the // build system. SpeculationPathStatusBuilding SpeculationPathStatus = "building" // SpeculationPathStatusPassed indicates the path's build completed // successfully. This is a terminal state. SpeculationPathStatusPassed SpeculationPathStatus = "passed" // SpeculationPathStatusFailed indicates the path's build did not complete // successfully. This is a terminal state. SpeculationPathStatusFailed SpeculationPathStatus = "failed" // SpeculationPathStatusCancelling is the non-terminal intent state set when // the path's build is being cancelled. The build holds its slot until it // reaches a terminal state. SpeculationPathStatusCancelling SpeculationPathStatus = "cancelling" // SpeculationPathStatusCancelled indicates the path's build was cancelled. // This is a terminal state. SpeculationPathStatusCancelled SpeculationPathStatus = "cancelled" )
func (SpeculationPathStatus) IsTerminal ¶
func (s SpeculationPathStatus) IsTerminal() bool
IsTerminal returns true if the status represents a final state (Passed, Failed, or Cancelled). Cancelling is intentionally excluded: it is a non-terminal intent, and the build may still reach Passed or Failed before it reaches Cancelled.