mirror of
https://github.com/therootcompany/golib.git
synced 2026-04-24 20:58:00 +00:00
refactor(check-ip): add IPCheck.Sync for geoip, reuse for tick
geoip now syncs via an IPCheck.Sync() method that returns (updated, err) — same signature as gitshallow.Repo.Sync / Fetcher.Fetch. The initial load and the background refresh goroutine both call it, so there is no duplicated fetch+open+swap logic.
This commit is contained in:
parent
b9295608db
commit
0c95156d4c
@ -42,9 +42,31 @@ type IPCheck struct {
|
|||||||
// the .tar.gz archives must already exist in <CacheDir>/maxmind/.
|
// the .tar.gz archives must already exist in <CacheDir>/maxmind/.
|
||||||
GeoIPBasicAuth string
|
GeoIPBasicAuth string
|
||||||
|
|
||||||
inbound *dataset.View[ipcohort.Cohort]
|
inbound *dataset.View[ipcohort.Cohort]
|
||||||
outbound *dataset.View[ipcohort.Cohort]
|
outbound *dataset.View[ipcohort.Cohort]
|
||||||
geo atomic.Pointer[geoip.Databases]
|
geoFetcher dataset.Fetcher
|
||||||
|
geo atomic.Pointer[geoip.Databases]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync fetches the GeoIP archives (via httpcache when basic auth is set,
|
||||||
|
// otherwise by polling their mtime) and, when the fetcher reports a change,
|
||||||
|
// re-opens the databases and atomically swaps the active snapshot.
|
||||||
|
func (c *IPCheck) Sync() (bool, error) {
|
||||||
|
updated, err := c.geoFetcher.Fetch()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if c.geo.Load() != nil && !updated {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
db, err := geoip.Open(filepath.Join(c.CacheDir, "maxmind"))
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if old := c.geo.Swap(db); old != nil {
|
||||||
|
_ = old.Close()
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -135,10 +157,8 @@ func main() {
|
|||||||
// httpcache conditional GETs. Without them, poll the existing tar.gz
|
// httpcache conditional GETs. Without them, poll the existing tar.gz
|
||||||
// files in maxmindDir. geoip.Open extracts in-memory — no .mmdb files
|
// files in maxmindDir. geoip.Open extracts in-memory — no .mmdb files
|
||||||
// are written to disk.
|
// are written to disk.
|
||||||
maxmindDir := filepath.Join(cfg.CacheDir, "maxmind")
|
cityTarPath := filepath.Join(cfg.CacheDir, "maxmind", "GeoLite2-City.tar.gz")
|
||||||
cityTarPath := filepath.Join(maxmindDir, "GeoLite2-City.tar.gz")
|
asnTarPath := filepath.Join(cfg.CacheDir, "maxmind", "GeoLite2-ASN.tar.gz")
|
||||||
asnTarPath := filepath.Join(maxmindDir, "GeoLite2-ASN.tar.gz")
|
|
||||||
var geoFetcher dataset.Fetcher
|
|
||||||
if cfg.GeoIPBasicAuth != "" {
|
if cfg.GeoIPBasicAuth != "" {
|
||||||
city := &httpcache.Cacher{
|
city := &httpcache.Cacher{
|
||||||
URL: geoip.DownloadBase + "/GeoLite2-City/download?suffix=tar.gz",
|
URL: geoip.DownloadBase + "/GeoLite2-City/download?suffix=tar.gz",
|
||||||
@ -154,7 +174,7 @@ func main() {
|
|||||||
AuthHeader: "Authorization",
|
AuthHeader: "Authorization",
|
||||||
AuthValue: cfg.GeoIPBasicAuth,
|
AuthValue: cfg.GeoIPBasicAuth,
|
||||||
}
|
}
|
||||||
geoFetcher = dataset.FetcherFunc(func() (bool, error) {
|
cfg.geoFetcher = dataset.FetcherFunc(func() (bool, error) {
|
||||||
cityUpdated, err := city.Fetch()
|
cityUpdated, err := city.Fetch()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("fetch GeoLite2-City: %w", err)
|
return false, fmt.Errorf("fetch GeoLite2-City: %w", err)
|
||||||
@ -166,16 +186,11 @@ func main() {
|
|||||||
return cityUpdated || asnUpdated, nil
|
return cityUpdated || asnUpdated, nil
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
geoFetcher = dataset.PollFiles(cityTarPath, asnTarPath)
|
cfg.geoFetcher = dataset.PollFiles(cityTarPath, asnTarPath)
|
||||||
}
|
}
|
||||||
if _, err := geoFetcher.Fetch(); err != nil {
|
if _, err := cfg.Sync(); err != nil {
|
||||||
log.Fatalf("geoip: %v", err)
|
log.Fatalf("geoip: %v", err)
|
||||||
}
|
}
|
||||||
geoDB, err := geoip.Open(maxmindDir)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("geoip: %v", err)
|
|
||||||
}
|
|
||||||
cfg.geo.Store(geoDB)
|
|
||||||
defer func() { _ = cfg.geo.Load().Close() }()
|
defer func() { _ = cfg.geo.Load().Close() }()
|
||||||
|
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
@ -198,21 +213,8 @@ func main() {
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
updated, err := geoFetcher.Fetch()
|
if _, err := cfg.Sync(); err != nil {
|
||||||
if err != nil {
|
|
||||||
log.Printf("geoip refresh: %v", err)
|
log.Printf("geoip refresh: %v", err)
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !updated {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
db, err := geoip.Open(maxmindDir)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("geoip refresh: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if old := cfg.geo.Swap(db); old != nil {
|
|
||||||
_ = old.Close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user