"Behind" means not running what the mesh would send
It meant "failed or refused". So a machine that applied cleanly and whose declaration has since changed was not behind — and novox/hq ADR 0010's question, did my change go out?, was answerable exactly for the machines that broke. For every machine that worked, the answer was silence whether the change had gone out or not, which is the thing replacing a pipeline was supposed not to cost. The mesh now records a digest of what it last sent each machine. A digest rather than the declaration: it can compute what a machine should be at any moment, and keeping a copy would be a second account of it able to disagree with the first. What cannot be recomputed is what was actually sent. Recorded after the send, not before — a digest kept for something that failed to send would make the machine look current for a declaration it never received. Never told stays separate from out of date. The remedy is the same push and the situations are not alike: nobody has ever asked that machine to be anything. And a machine the mesh could not work out is not reported as waiting, because saying so would invent a comparison — that is `plan`'s answer to give. `status` says it and `push --behind` sends it, or the flag would know something the person reading the status does not.
This commit is contained in:
@@ -513,3 +513,66 @@ func (i *Inventory) DoingOf(ctx context.Context, name string) (Doing, bool, erro
|
||||
}
|
||||
return d, true, nil
|
||||
}
|
||||
|
||||
// RecordSent keeps a digest of the declaration a machine was last sent.
|
||||
//
|
||||
// **A digest rather than the declaration.** The mesh can compute what a machine should be at any
|
||||
// moment; keeping a copy would be a second account of it, able to disagree with the first. What
|
||||
// cannot be recomputed is what was *actually sent*, and that is the whole difference between a
|
||||
// machine that is out of date and one that has never been told.
|
||||
func (i *Inventory) RecordSent(ctx context.Context, node, digest string) error {
|
||||
_, err := i.store.Pool().Exec(ctx,
|
||||
`update node set sent = $2, sent_at = now() where id = $1`, node, digest)
|
||||
return err
|
||||
}
|
||||
|
||||
// Waiting is every machine whose declaration has changed since it was last sent one.
|
||||
//
|
||||
// The caller works out what each machine should be now, because only it can — resolution is the
|
||||
// control plane's and this context holds records. What is answered here is the comparison.
|
||||
//
|
||||
// **A machine that has never been sent anything is waiting**, and says so differently: it is not
|
||||
// out of date, it has never been told, and the remedy is the same push while the situation is not
|
||||
// the same at all.
|
||||
func (i *Inventory) Waiting(ctx context.Context, would map[string]string) ([]Machine, error) {
|
||||
rows, err := i.store.Pool().Query(ctx,
|
||||
`select name, coalesce(sent, ''), sent_at from node order by name`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var out []Machine
|
||||
for rows.Next() {
|
||||
var m Machine
|
||||
var at *time.Time
|
||||
if err := rows.Scan(&m.Node, &m.Sent, &at); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.SentAt = at
|
||||
wanted, known := would[m.Node]
|
||||
if !known {
|
||||
// Nothing was computed for it — it resolves to nothing, or the caller did not ask.
|
||||
// Silence rather than a guess: saying "waiting" about a machine nobody worked out
|
||||
// would be inventing a comparison.
|
||||
continue
|
||||
}
|
||||
if m.Sent == wanted {
|
||||
continue
|
||||
}
|
||||
m.Never = m.Sent == ""
|
||||
out = append(out, m)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// Machine is one machine that has not been sent what it should be.
|
||||
type Machine struct {
|
||||
Node string
|
||||
// Sent is the digest it last received, empty if it has never received one.
|
||||
Sent string
|
||||
SentAt *time.Time
|
||||
// Never is true when it has never been sent anything, which is a different situation from
|
||||
// being out of date and reads differently to whoever is looking.
|
||||
Never bool
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user