diff --git a/net/gitshallow/gitshallow.go b/net/gitshallow/gitshallow.go index 35030eb..80ae863 100644 --- a/net/gitshallow/gitshallow.go +++ b/net/gitshallow/gitshallow.go @@ -16,8 +16,7 @@ type Repo struct { Depth int // 0 defaults to 1, -1 for all Branch string // Optional: specific branch to clone/pull - mu sync.Mutex - callbacks []func() error + mu sync.Mutex } // New creates a new Repo instance. @@ -33,27 +32,18 @@ func New(url, path string, depth int, branch string) *Repo { } } -// Register adds a callback invoked after each successful clone or pull. -// Use this to reload files and update atomic pointers when the repo changes. -func (r *Repo) Register(fn func() error) { - r.callbacks = append(r.callbacks, fn) -} - -// Init clones the repo if missing, syncs once, then invokes all callbacks -// regardless of whether git had new commits — ensuring files are loaded on startup. -func (r *Repo) Init(lightGC bool) error { +// Init clones the repo if missing, then syncs once. +// Returns whether anything new was fetched. +func (r *Repo) Init(lightGC bool) (bool, error) { gitDir := filepath.Join(r.Path, ".git") if _, err := os.Stat(gitDir); err != nil { if _, err := r.Clone(); err != nil { - return err + return false, err } } - if _, err := r.syncGit(lightGC); err != nil { - return err - } - - return r.invokeCallbacks() + updated, err := r.syncGit(lightGC) + return updated, err } // Clone performs a shallow clone (--depth N --single-branch --no-tags). @@ -182,16 +172,10 @@ func (r *Repo) gc(aggressiveGC, pruneNow bool) error { return err } -// Sync clones if missing, pulls, runs GC, and invokes callbacks if HEAD changed. -// Returns whether HEAD changed. -// lightGC=false (zero value) runs aggressive GC with --prune=now to minimize disk use. -func (r *Repo) Sync(lightGC bool) (updated bool, err error) { - updated, err = r.syncGit(lightGC) - if err != nil || !updated { - return updated, err - } - - return true, r.invokeCallbacks() +// Sync clones if missing, pulls, and runs GC. Returns whether HEAD changed. +// lightGC=false runs aggressive GC with --prune=now to minimize disk use. +func (r *Repo) Sync(lightGC bool) (bool, error) { + return r.syncGit(lightGC) } func (r *Repo) syncGit(lightGC bool) (updated bool, err error) { @@ -211,12 +195,3 @@ func (r *Repo) syncGit(lightGC bool) (updated bool, err error) { return true, r.gc(!lightGC, !lightGC) } - -func (r *Repo) invokeCallbacks() error { - for _, fn := range r.callbacks { - if err := fn(); err != nil { - fmt.Fprintf(os.Stderr, "error: reload callback: %v\n", err) - } - } - return nil -} diff --git a/net/httpcache/httpcache.go b/net/httpcache/httpcache.go index 2a76d60..7f39b9d 100644 --- a/net/httpcache/httpcache.go +++ b/net/httpcache/httpcache.go @@ -12,16 +12,15 @@ import ( const defaultTimeout = 30 * time.Second // Cacher fetches a URL to a local file, using ETag/Last-Modified to skip -// unchanged responses. Calls registered callbacks when the file changes. +// unchanged responses. type Cacher struct { URL string Path string Timeout time.Duration // 0 uses 30s - mu sync.Mutex - etag string - lastMod string - callbacks []func() error + mu sync.Mutex + etag string + lastMod string } // New creates a Cacher that fetches URL and writes it to path. @@ -29,34 +28,8 @@ func New(url, path string) *Cacher { return &Cacher{URL: url, Path: path} } -// Register adds a callback invoked after each successful fetch. -func (c *Cacher) Register(fn func() error) { - c.callbacks = append(c.callbacks, fn) -} - -// Init fetches the URL unconditionally (no cached headers yet) and invokes -// all callbacks, ensuring files are loaded on startup. -func (c *Cacher) Init() error { - if _, err := c.Fetch(); err != nil { - return err - } - return c.invokeCallbacks() -} - -// Sync sends a conditional GET, writes updated content, and invokes callbacks. -// Returns whether the file was updated. -func (c *Cacher) Sync() (updated bool, err error) { - updated, err = c.Fetch() - if err != nil || !updated { - return updated, err - } - return true, c.invokeCallbacks() -} - // Fetch sends a conditional GET and writes new content to Path if the server -// responds with 200. Returns whether the file was updated. Does not invoke -// callbacks — use Sync for the single-cacher case, or call Fetch across -// multiple cachers and handle the reload yourself. +// responds with 200. Returns whether the file was updated. func (c *Cacher) Fetch() (updated bool, err error) { c.mu.Lock() defer c.mu.Unlock() @@ -118,12 +91,3 @@ func (c *Cacher) Fetch() (updated bool, err error) { return true, nil } - -func (c *Cacher) invokeCallbacks() error { - for _, fn := range c.callbacks { - if err := fn(); err != nil { - fmt.Fprintf(os.Stderr, "error: reload callback: %v\n", err) - } - } - return nil -} diff --git a/net/ipcohort/cmd/check-ip-blacklist/blacklist.go b/net/ipcohort/cmd/check-ip-blacklist/blacklist.go index b184a31..9bf69c4 100644 --- a/net/ipcohort/cmd/check-ip-blacklist/blacklist.go +++ b/net/ipcohort/cmd/check-ip-blacklist/blacklist.go @@ -30,8 +30,8 @@ type IPFilter struct { inboundPaths []string outboundPaths []string - git *gitshallow.Repo - httpInbound []*httpcache.Cacher + git *gitshallow.Repo + httpInbound []*httpcache.Cacher httpOutbound []*httpcache.Cacher } @@ -47,7 +47,6 @@ func NewFileFilter(whitelist, inbound, outbound []string) *IPFilter { // NewGitFilter clones/pulls gitURL into repoDir and loads the given relative // paths for each cohort on each update. func NewGitFilter(gitURL, repoDir string, whitelist, inboundRel, outboundRel []string) *IPFilter { - repo := gitshallow.New(gitURL, repoDir, 1, "") abs := func(rel []string) []string { out := make([]string, len(rel)) for i, p := range rel { @@ -55,14 +54,12 @@ func NewGitFilter(gitURL, repoDir string, whitelist, inboundRel, outboundRel []s } return out } - f := &IPFilter{ + return &IPFilter{ whitelistPaths: whitelist, inboundPaths: abs(inboundRel), outboundPaths: abs(outboundRel), - git: repo, + git: gitshallow.New(gitURL, repoDir, 1, ""), } - repo.Register(f.reloadAll) - return f } // NewHTTPFilter fetches inbound and outbound sources via HTTP; @@ -83,7 +80,9 @@ func NewHTTPFilter(whitelist []string, inbound, outbound []HTTPSource) *IPFilter func (f *IPFilter) Init(lightGC bool) error { switch { case f.git != nil: - return f.git.Init(lightGC) + if _, err := f.git.Init(lightGC); err != nil { + return err + } case len(f.httpInbound) > 0 || len(f.httpOutbound) > 0: for _, c := range f.httpInbound { if _, err := c.Fetch(); err != nil { @@ -95,10 +94,8 @@ func (f *IPFilter) Init(lightGC bool) error { return err } } - return f.reloadAll() - default: - return f.reloadAll() } + return f.reloadAll() } func (f *IPFilter) Run(ctx context.Context, lightGC bool) { @@ -124,7 +121,11 @@ func (f *IPFilter) Run(ctx context.Context, lightGC bool) { func (f *IPFilter) sync(lightGC bool) (bool, error) { switch { case f.git != nil: - return f.git.Sync(lightGC) + updated, err := f.git.Sync(lightGC) + if err != nil || !updated { + return updated, err + } + return true, f.reloadAll() case len(f.httpInbound) > 0 || len(f.httpOutbound) > 0: var anyUpdated bool for _, c := range f.httpInbound {