latest: report each Poll Lane's last pass to the owner's page (#102)
A Lane's pace, its refusal backoff and whether its Site needs the browser were only ever visible in the log. The admin page (issue #102) has to state them, so the Poller keeps one snapshot per Lane. - LaneState/Status (status.go) is the page's view of a Lane: due, gap, clamped, refusing, browser. - runOnce records a snapshot on every return path, including the pass that refuses, so a cooling Lane does not read as one that never ran. - Refusing is derived at snapshot read time from the backoff, not stored: a Lane that cooled down between passes must report false without a new pass. - LaneStatus reports only Sites that have completed a pass, so a fresh restart renders "no data yet" instead of confident zeroes.
This commit is contained in:
@@ -57,6 +57,10 @@ type Poller struct {
|
||||
mu sync.Mutex
|
||||
refuseUntil map[string]time.Time
|
||||
browserDownAt time.Time
|
||||
// laneStates is the owner's page snapshot of each Lane's last pass
|
||||
// (issue #102), keyed by Site. Guarded by mu; a Site appears only after
|
||||
// its first pass, so a restart renders "no data yet" rather than zeroes.
|
||||
laneStates map[string]LaneState
|
||||
// coverWG tracks in-flight cover work. Covers heal in the background so a
|
||||
// slow cover host cannot delay the next Series-page Poll; tests join it
|
||||
// before asserting on cover fetches.
|
||||
@@ -218,6 +222,10 @@ func (p *Poller) runOnce(ctx context.Context) {
|
||||
// production Lane's rate limit; the deterministic test entry runs back to back.
|
||||
func (p *Poller) runLanePass(ctx context.Context, name string, paced bool) time.Duration {
|
||||
now := p.Now()
|
||||
// Snapshot this pass for the owner's page (issue #102). Recorded on every
|
||||
// return path, with the figures filled in where the pass computes them.
|
||||
st := LaneState{Site: name, LastRun: now, Browser: isBrowserSite(name)}
|
||||
defer func() { p.recordLaneState(st) }()
|
||||
if until := p.refusalBackoff(name); now.Before(until) {
|
||||
// Cooling down after a refusal: do not attempt this Site at all.
|
||||
return until.Sub(now)
|
||||
@@ -246,6 +254,7 @@ func (p *Poller) runLanePass(ctx context.Context, name string, paced bool) time.
|
||||
log.Printf("latest poll %s: due query: %v", name, err)
|
||||
return defaultGap
|
||||
}
|
||||
st.Due = len(due)
|
||||
if s.Browser != nil && f == p.BrowserFetch && !browserWakeDue(due, now, s.Rest) {
|
||||
// Below both thresholds Chrome stays asleep (ADR-0005 on-demand
|
||||
// browser): waking it for a single Poll would cost a challenge solve
|
||||
@@ -268,6 +277,7 @@ func (p *Poller) runLanePass(ctx context.Context, name string, paced bool) time.
|
||||
return defaultGap
|
||||
}
|
||||
gap, clamped := effectiveGap(s, eligible)
|
||||
st.Gap, st.Clamped = gap, clamped
|
||||
if clamped {
|
||||
log.Printf("latest poll %s: gap clamped to %s floor (eligible series=%d)", name, minGap, eligible)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user