Keep rollouts and the merges they answer in the rollouts bucket (issue 1092)
Once chain_moved records the kind, a plan is a key of the rollouts bucket under its id and the open batch is the same key in state assembling. A save refuses a copy another save moved since (the plan's own Revision, kept in its value, counts saves) and keeps the merges the record holds, so a copy read before a merge moved cannot lay it back. The merges a batch or walk answers are the record's held field, with the columns the table had; a merge no plan answers stays, flagged, in the record that held it last, or in the record kept for those. A merge moved to a plan is written to the receiving record first and then taken from the giving one; one found in both is read from the one it entered last and repaired at the next cut. Plans and merges are read from a view kept by one watch of the bucket. A bus that does not answer, a lease lost and a key moved are now not-now like the store being away, so a merge whose plan could not be written is held and handed over again, never acknowledged. The start moves release_plan and batched_merge into the bucket, one kind, counted against both tables.
This commit is contained in:
@@ -33,6 +33,11 @@ type BatchedMerge struct {
|
||||
|
||||
// AddMerge keeps a merge for a plan; false when the merge was kept already, for whatever plan.
|
||||
func (i *Inventory) AddMerge(ctx context.Context, m BatchedMerge) (bool, error) {
|
||||
if c, on, err := i.ChainReads(ctx, KindRollouts); err != nil {
|
||||
return false, err
|
||||
} else if on {
|
||||
return i.chainAddMerge(ctx, c, m)
|
||||
}
|
||||
tag, err := i.store.Pool().Exec(ctx,
|
||||
`insert into batched_merge (repository, branch, commit_hash, merged_at, heard_at, event, plan_id, alone)
|
||||
values (lower($1), $2, $3, $4, $5, $6, nullif($7, ''), $8) on conflict do nothing`,
|
||||
@@ -45,6 +50,11 @@ func (i *Inventory) AddMerge(ctx context.Context, m BatchedMerge) (bool, error)
|
||||
|
||||
// MergeOf is one kept merge; false when it was never heard.
|
||||
func (i *Inventory) MergeOf(ctx context.Context, repository, commit string) (BatchedMerge, bool, error) {
|
||||
if c, on, err := i.ChainReads(ctx, KindRollouts); err != nil {
|
||||
return BatchedMerge{}, false, err
|
||||
} else if on {
|
||||
return i.chainMergeOf(ctx, c, repository, commit)
|
||||
}
|
||||
ms, err := i.merges(ctx, `where repository = lower($1) and commit_hash = $2`, repository, commit)
|
||||
if err != nil || len(ms) == 0 {
|
||||
return BatchedMerge{}, false, err
|
||||
@@ -54,12 +64,22 @@ func (i *Inventory) MergeOf(ctx context.Context, repository, commit string) (Bat
|
||||
|
||||
// MergesOf is every merge a plan answers, oldest merge first.
|
||||
func (i *Inventory) MergesOf(ctx context.Context, plan string) ([]BatchedMerge, error) {
|
||||
if c, on, err := i.ChainReads(ctx, KindRollouts); err != nil {
|
||||
return nil, err
|
||||
} else if on {
|
||||
return i.chainMergesOf(ctx, c, plan)
|
||||
}
|
||||
return i.merges(ctx, `where plan_id = $1 order by merged_at nulls last, heard_at`, plan)
|
||||
}
|
||||
|
||||
// LaterMergesOf is every merge of a repository's branch made after a moment and answered by a plan, the
|
||||
// newest first.
|
||||
func (i *Inventory) LaterMergesOf(ctx context.Context, repository, branch string, after time.Time) ([]BatchedMerge, error) {
|
||||
if c, on, err := i.ChainReads(ctx, KindRollouts); err != nil {
|
||||
return nil, err
|
||||
} else if on {
|
||||
return i.chainLaterMergesOf(ctx, c, repository, branch, after)
|
||||
}
|
||||
return i.merges(ctx, `where repository = lower($1) and branch = $2 and merged_at > $3 and plan_id is not null
|
||||
order by merged_at desc`, repository, branch, after)
|
||||
}
|
||||
@@ -67,6 +87,11 @@ func (i *Inventory) LaterMergesOf(ctx context.Context, repository, branch string
|
||||
// KeptOnBranch says the controller keeps a merge of a repository's branch, and when it heard the branch's first: a merge of a branch it keeps merges of, made since then, is the record's to answer, whatever a
|
||||
// module's last look says (novox/hq ADR 0276).
|
||||
func (i *Inventory) KeptOnBranch(ctx context.Context, repository, branch string) (bool, time.Time, error) {
|
||||
if c, on, err := i.ChainReads(ctx, KindRollouts); err != nil {
|
||||
return false, time.Time{}, err
|
||||
} else if on {
|
||||
return i.chainKeptOnBranch(ctx, c, repository, branch)
|
||||
}
|
||||
var first *time.Time
|
||||
var kept bool
|
||||
err := i.store.Pool().QueryRow(ctx,
|
||||
@@ -80,12 +105,22 @@ func (i *Inventory) KeptOnBranch(ctx context.Context, repository, branch string)
|
||||
|
||||
// AloneMerges is every merge waiting to be walked on its own commit, the newest first (ADR 0276 decision 3).
|
||||
func (i *Inventory) AloneMerges(ctx context.Context) ([]BatchedMerge, error) {
|
||||
if c, on, err := i.ChainReads(ctx, KindRollouts); err != nil {
|
||||
return nil, err
|
||||
} else if on {
|
||||
return i.chainAloneMerges(ctx, c)
|
||||
}
|
||||
return i.merges(ctx, `where plan_id is null and alone order by merged_at desc nulls last, heard_at desc`)
|
||||
}
|
||||
|
||||
// AnswerMerge moves a merge to the plan that answers it now; an empty plan with alone leaves it waiting to
|
||||
// be walked on its own commit.
|
||||
func (i *Inventory) AnswerMerge(ctx context.Context, repository, commit, plan string, alone bool) error {
|
||||
if c, on, err := i.ChainReads(ctx, KindRollouts); err != nil {
|
||||
return err
|
||||
} else if on {
|
||||
return i.chainSavePlans(ctx, c, nil, []MergeMove{{Repository: repository, Commit: commit, Plan: plan, Alone: alone}})
|
||||
}
|
||||
_, err := i.store.Pool().Exec(ctx,
|
||||
`update batched_merge set plan_id = nullif($3, ''), alone = $4 where repository = lower($1) and commit_hash = $2`,
|
||||
repository, commit, plan, alone)
|
||||
@@ -95,6 +130,11 @@ func (i *Inventory) AnswerMerge(ctx context.Context, repository, commit, plan st
|
||||
// Batches is every batch not yet cut: assembling or queued, oldest first. One at a time is the rule; more
|
||||
// are read so a fault is seen.
|
||||
func (i *Inventory) Batches(ctx context.Context) ([]Plan, error) {
|
||||
if c, on, err := i.ChainReads(ctx, KindRollouts); err != nil {
|
||||
return nil, err
|
||||
} else if on {
|
||||
return i.chainPlans(ctx, c, func(e viewEntry) bool { return e.sum.State == PlanAssembling || e.sum.State == PlanQueued }, sortCreated)
|
||||
}
|
||||
return i.plans(ctx, `where state in ('assembling', 'queued') order by created`)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user