A walk let go behind another reads as a wait: its note on the line, never late, and no tier of it watched (hq ADR 0276 review of #200)
This commit is contained in:
@@ -624,6 +624,20 @@ func TestAWalkLetGoBesideAStartedOneStartsOnceItEnded(t *testing.T) {
|
|||||||
if len(*asked) != before || !strings.Contains(got.Note, "starts once "+started[0].ID) {
|
if len(*asked) != before || !strings.Contains(got.Note, "starts once "+started[0].ID) {
|
||||||
t.Fatalf("a walk let go beside a started one asked (%d → %d) or does not say it waits: %q", before, len(*asked), got.Note)
|
t.Fatalf("a walk let go beside a started one asked (%d → %d) or does not say it waits: %q", before, len(*asked), got.Note)
|
||||||
}
|
}
|
||||||
|
// Read as a wait, an hour on: its note on the line, never LATE, and no tier of it late for S3.
|
||||||
|
later := time.Now().Add(time.Hour)
|
||||||
|
if line := planLine(got, later); !strings.Contains(line, "starts once "+started[0].ID) || strings.Contains(line, "LATE") {
|
||||||
|
t.Fatalf("a deferred walk reads %q", line)
|
||||||
|
}
|
||||||
|
facts, _, err := gatherPlans(ctx, open.inventory, later, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
for _, f := range facts {
|
||||||
|
if f.id == got.ID {
|
||||||
|
t.Fatalf("a deferred walk is watched as a tier running late: %+v", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
done := started[0]
|
done := started[0]
|
||||||
done.State = inventory.PlanDone
|
done.State = inventory.PlanDone
|
||||||
if err := open.inventory.SavePlan(ctx, &done); err != nil {
|
if err := open.inventory.SavePlan(ctx, &done); err != nil {
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ func planBuilt(ctx context.Context, open *stores, module, commit, failed string,
|
|||||||
|
|
||||||
// startedBeside is the id of a started walk open beside this one — a merge's walk past its wait, not the
|
// startedBeside is the id of a started walk open beside this one — a merge's walk past its wait, not the
|
||||||
// backlog's — or empty: one walk at a time (novox/hq ADR 0276).
|
// backlog's — or empty: one walk at a time (novox/hq ADR 0276).
|
||||||
func startedBeside(ctx context.Context, inv *inventory.Inventory, id string) (string, error) {
|
func startedBeside(ctx context.Context, inv *inventory.Inventory, id string, created time.Time) (string, error) {
|
||||||
plans, err := inv.OpenPlans(ctx)
|
plans, err := inv.OpenPlans(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -458,13 +458,21 @@ func startedBeside(ctx context.Context, inv *inventory.Inventory, id string) (st
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Started: a tier asked, or on its way (let go, or waiting for nobody) before this one.
|
// Started: a tier asked, or on its way (let go, or waiting for nobody) before this one.
|
||||||
if q.Tier > 0 || askedAny(q) || q.Created.Before(createdOf(ctx, inv, id)) {
|
if q.Tier > 0 || askedAny(q) || q.Created.Before(created) {
|
||||||
return q.ID, nil
|
return q.ID, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deferred says a walk has its word and has not started: let go while another walk was started, it waits for
|
||||||
|
// that one to end (startedBeside). Read as a wait, not as a tier running late: `plans` and `status` say its
|
||||||
|
// note, and S3 leaves it out.
|
||||||
|
func deferred(p inventory.Plan) bool {
|
||||||
|
return p.Open() && p.Release == nil && p.Tier == 0 && !askedAny(p) && p.Delivery != nil &&
|
||||||
|
p.Delivery.Awaits != "" && p.Delivery.Go != nil
|
||||||
|
}
|
||||||
|
|
||||||
// askedAny says a plan asked any module.
|
// askedAny says a plan asked any module.
|
||||||
func askedAny(p inventory.Plan) bool {
|
func askedAny(p inventory.Plan) bool {
|
||||||
for _, s := range p.Modules {
|
for _, s := range p.Modules {
|
||||||
@@ -475,15 +483,6 @@ func askedAny(p inventory.Plan) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// createdOf is when a plan was made; zero when it cannot be read.
|
|
||||||
func createdOf(ctx context.Context, inv *inventory.Inventory, id string) time.Time {
|
|
||||||
p, err := inv.PlanByID(ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
return p.Created
|
|
||||||
}
|
|
||||||
|
|
||||||
// advancePlans moves every open plan as far as the facts allow: a tier whose modules are all built
|
// advancePlans moves every open plan as far as the facts allow: a tier whose modules are all built
|
||||||
// and whose gates are applied gives way to the next; the last tier done is the plan done. Called
|
// and whose gates are applied gives way to the next; the last tier done is the plan done. Called
|
||||||
// after every outcome and on a timer, so a plan waiting on a machine's report moves when it comes.
|
// after every outcome and on a timer, so a plan waiting on a machine's report moves when it comes.
|
||||||
@@ -619,7 +618,7 @@ func advanceOnce(ctx context.Context, open *stores, p *inventory.Plan,
|
|||||||
// **One walk at a time** (novox/hq ADR 0276): a walk about to ask its first tier while another started
|
// **One walk at a time** (novox/hq ADR 0276): a walk about to ask its first tier while another started
|
||||||
// walk is open waits for that one to end, let go or not, and says so.
|
// walk is open waits for that one to end, let go or not, and says so.
|
||||||
if p.Tier == 0 {
|
if p.Tier == 0 {
|
||||||
if behind, err := startedBeside(ctx, inv, p.ID); err != nil {
|
if behind, err := startedBeside(ctx, inv, p.ID, p.Created); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
} else if behind != "" {
|
} else if behind != "" {
|
||||||
note := fmt.Sprintf("let go; starts once %s ended — one walk at a time", behind)
|
note := fmt.Sprintf("let go; starts once %s ended — one walk at a time", behind)
|
||||||
@@ -1257,6 +1256,10 @@ func planLineOn(p inventory.Plan, now time.Time, pause pauseView, bound time.Dur
|
|||||||
// Waiting for its delivery's word is no lateness of the walk's (novox/hq ADR 0239).
|
// Waiting for its delivery's word is no lateness of the walk's (novox/hq ADR 0239).
|
||||||
return fmt.Sprintf("%s · %s, %s, for %s", name, where, waitingNote(p), since)
|
return fmt.Sprintf("%s · %s, %s, for %s", name, where, waitingNote(p), since)
|
||||||
}
|
}
|
||||||
|
if deferred(p) {
|
||||||
|
// Nor is waiting for the walk before it to end (one walk at a time, novox/hq ADR 0276).
|
||||||
|
return fmt.Sprintf("%s · %s, %s, for %s", name, where, p.Note, since)
|
||||||
|
}
|
||||||
if waiting, paused := pausedWaiting(p, pause, now); paused {
|
if waiting, paused := pausedWaiting(p, pause, now); paused {
|
||||||
return fmt.Sprintf("%s · %s, %s", name, where, waiting)
|
return fmt.Sprintf("%s · %s, %s", name, where, waiting)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -490,6 +490,11 @@ func gatherPlans(ctx context.Context, inv *inventory.Inventory, now time.Time, b
|
|||||||
awaits: p.Delivery.Awaits, since: p.Created, modules: planModules(p), merges: p.Delivery.Merges})
|
awaits: p.Delivery.Awaits, since: p.Created, modules: planModules(p), merges: p.Delivery.Merges})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// A walk let go and waiting for the walk before it to end (ADR 0276) is no tier late either: the walk
|
||||||
|
// before it is the one S3 watches.
|
||||||
|
if deferred(p) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
_, paused := pausedWaiting(p, pause, now)
|
_, paused := pausedWaiting(p, pause, now)
|
||||||
bound := bounds.of(p.Repository)
|
bound := bounds.of(p.Repository)
|
||||||
out = append(out, planFacts{id: p.ID, repository: p.Repository, commit: p.Commit, tier: p.Tier,
|
out = append(out, planFacts{id: p.ID, repository: p.Repository, commit: p.Commit, tier: p.Tier,
|
||||||
|
|||||||
Reference in New Issue
Block a user