Files
EvoBGP/internal/pipeline/asn_cache.go
T
DenozordecandCursor a8c5e9701f perf: optimize data path, indexes and frontend virtualization
- Убран latestCDNRowsBySource; expanded BIRD preview генерируется on-demand
- Batch AS meta updates; миграция perf-индексов 000012
- VirtualPrefixList для preview префиксов; метрики pipeline refresh
- PolitePause для RIPEstat после cache miss

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 10:45:39 +07:00

60 lines
1.5 KiB
Go

package pipeline
import (
"context"
"fmt"
"net/http"
"net/netip"
"os"
"strconv"
"strings"
"time"
"evobgp/internal/asnresolve"
"evobgp/internal/store"
)
func asnCacheTTL() time.Duration {
sec := 1800
if s := strings.TrimSpace(os.Getenv("EVOBGP_ASN_CACHE_TTL_SEC")); s != "" {
if v, err := strconv.Atoi(s); err == nil && v > 0 {
sec = v
}
}
return time.Duration(sec) * time.Second
}
// resolveASNForEntry fetches prefixes and holder with shared TTL cache (asn_prefix_cache).
func resolveASNForEntry(ctx context.Context, st store.Backend, hc *http.Client, asn int64) ([]netip.Prefix, string, error) {
ttl := asnCacheTTL()
if st != nil {
if ent, ok, err := st.GetASNPrefixCache(asn); err == nil && ok && ent != nil && time.Since(ent.FetchedAt) < ttl {
out := make([]netip.Prefix, 0, len(ent.Prefixes))
for _, p := range ent.Prefixes {
pfx, perr := netip.ParsePrefix(strings.TrimSpace(p))
if perr != nil {
continue
}
out = append(out, pfx.Masked())
}
return out, ent.Holder, nil
}
}
pfxs, err := asnresolve.AnnouncedPrefixes(ctx, hc, asn)
if err != nil {
return nil, "", err
}
asnresolve.PolitePause()
holder, _ := asnresolve.ASHolderName(ctx, hc, asn)
if st != nil {
strs := make([]string, len(pfxs))
for i, p := range pfxs {
strs[i] = p.String()
}
if err := st.SetASNPrefixCache(asn, holder, strs); err != nil {
return nil, "", fmt.Errorf("asn cache AS%d: %w", asn, err)
}
}
return pfxs, holder, nil
}