refactor(dataset): Tick takes an onError callback, no more stderr

Libraries shouldn't decide where errors go. Tick now passes Load
errors to onError (nil to ignore); callers pick log/count/page.
check-ip supplies its own stderr writer.
This commit is contained in:
AJ ONeal 2026-04-20 14:19:26 -06:00
parent 912e1179d4
commit 786463cecd
No known key found for this signature in database
2 changed files with 9 additions and 8 deletions

View File

@ -246,7 +246,9 @@ func newChecker(ctx context.Context, cfg Config) (*Checker, func(), error) {
}
fmt.Fprintf(os.Stderr, "Loaded inbound=%d outbound=%d\n",
inbound.Value().Size(), outbound.Value().Size())
go group.Tick(ctx, refreshInterval)
go group.Tick(ctx, refreshInterval, func(err error) {
fmt.Fprintf(os.Stderr, "refresh: %v\n", err)
})
whitelist, err := loadWhitelist(cfg.Whitelist)
if err != nil {

View File

@ -16,8 +16,6 @@ package dataset
import (
"context"
"fmt"
"os"
"sync/atomic"
"time"
)
@ -81,9 +79,10 @@ func (g *Group) Load(ctx context.Context) error {
return nil
}
// Tick calls Load every interval until ctx is done. Errors are written to
// stderr and do not stop the loop.
func (g *Group) Tick(ctx context.Context, interval time.Duration) {
// Tick calls Load every interval until ctx is done. Load errors are passed to
// onError (if non-nil) and do not stop the loop; callers choose whether to log,
// count, page, or ignore. Run in a goroutine: `go g.Tick(ctx, d, onError)`.
func (g *Group) Tick(ctx context.Context, interval time.Duration, onError func(error)) {
t := time.NewTicker(interval)
defer t.Stop()
for {
@ -91,8 +90,8 @@ func (g *Group) Tick(ctx context.Context, interval time.Duration) {
case <-ctx.Done():
return
case <-t.C:
if err := g.Load(ctx); err != nil {
fmt.Fprintf(os.Stderr, "dataset: load error: %v\n", err)
if err := g.Load(ctx); err != nil && onError != nil {
onError(err)
}
}
}