fix: keep the legacy cover heal and no-chapter byte count (#94)

Restore two review findings against spec claims 'the Poll keeps its own
Cover policy' and 'pinning is the only behavioural change': prefetchCover
now also runs on ticks where the page fetch itself fails (the heal is
independent of the page read, and its source may answer while the origin
does not), and the no-chapter log surfaces the fetched body length again
via a BodyLen fact on seriesRead. Browser dispatch iterates the sorted
browser site list so its outcome cannot depend on map order.
This commit is contained in:
2026-08-12 00:29:42 +07:00
parent 5621202bcf
commit d998f8725c
6 changed files with 31 additions and 14 deletions
+8 -3
View File
@@ -226,11 +226,16 @@ func (p *Poller) checkOne(ctx context.Context, sr store.Series) {
// passes the gate is retried at cooldown pace rather than
// hot-looping.
log.Printf("latest poll %q: not fetchable: site=%q url=%q", sr.Key(), sr.Site, sr.SeriesURL)
return
case errors.Is(err, errNoFetcher):
log.Printf("latest poll %q: no fetcher for site %q", sr.Key(), sr.Site)
default:
log.Printf("latest poll %q: %v", sr.Key(), err)
return
}
// A legacy cover heals independently of the page read: its source may
// answer — a CDN — while the origin does not, so a fetch failure does
// not skip the heal, matching the order the shared read replaced.
p.prefetchCover(ctx, sr)
log.Printf("latest poll %q: %v", sr.Key(), err)
return
}
// A legacy cover source is healed independently of the page read.
@@ -241,7 +246,7 @@ func (p *Poller) checkOne(ctx context.Context, sr store.Series) {
if !facts.HasLatest {
// Most likely a challenge page or a layout change. Either way the row is
// already stamped, so this waits out a cooldown instead of hot-looping.
log.Printf("latest poll %q: no chapter links", sr.Key())
log.Printf("latest poll %q: no chapter links in %d bytes", sr.Key(), facts.BodyLen)
return
}