refactor(web): remove deprecated dashboard components and enhance KPI grid
quality / commitlint (push) Skipped
quality / changes (push) Successful in 9s
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 46s
quality / web (push) Successful in 1m16s
quality / go (push) Successful in 2m42s
quality / bird2 (push) Successful in 16s
CD / quality (push) Successful in 5m19s
CD / publish (push) Successful in 7m19s
quality / commitlint (push) Skipped
quality / changes (push) Successful in 9s
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 46s
quality / web (push) Successful in 1m16s
quality / go (push) Successful in 2m42s
quality / bird2 (push) Successful in 16s
CD / quality (push) Successful in 5m19s
CD / publish (push) Successful in 7m19s
- Deleted unused components: `DashboardActivityTimeline`, `DashboardFramePanel`, `DashboardModulesGrid`, `DashboardRecentJobsGrid`, and `DashboardRecentRevisionsGrid` to streamline the dashboard. - Updated `DashboardKpiGrid` to improve KPI display logic, including progress indicators and enhanced badge functionality. - Refactored `DashboardNetworkHealth` to provide better status representation based on loading states and network conditions. - Introduced new properties for KPI cards to support progress tracking and improved visual feedback. This cleanup aims to enhance performance and maintainability of the dashboard while providing a better user experience.
This commit is contained in:
@@ -24,28 +24,43 @@ func asnCacheTTL() time.Duration {
|
||||
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
|
||||
// asnHolderTTL is how long a holder name stays authoritative between refreshes;
|
||||
// holder text changes rarely, so it survives short prefix-cache TTLs.
|
||||
func asnHolderTTL() time.Duration {
|
||||
sec := 7 * 24 * 3600
|
||||
if s := strings.TrimSpace(os.Getenv("EVOBGP_ASN_HOLDER_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).
|
||||
// The holder lookup starts concurrently with the prefix fetch (one RTT instead of two);
|
||||
// a holder failure is non-fatal — the previously cached holder name is kept.
|
||||
func resolveASNForEntry(ctx context.Context, st store.Backend, hc *http.Client, asn int64) ([]netip.Prefix, string, error) {
|
||||
ttl := asnCacheTTL()
|
||||
var prevHolder string
|
||||
if st != nil {
|
||||
if ent, ok, err := st.GetASNPrefixCache(asn); err == nil && ok && ent != nil {
|
||||
prevHolder = ent.Holder
|
||||
if time.Since(ent.FetchedAt) < ttl {
|
||||
return parseASNCachePrefixes(ent.Prefixes), ent.Holder, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
holderCh := startASNHolderFetch(ctx, hc, st, asn, prevHolder)
|
||||
|
||||
pfxs, err := asnresolve.AnnouncedPrefixes(ctx, hc, asn)
|
||||
if err != nil {
|
||||
holder := <-holderCh // drain to avoid leaking the goroutine's channel send
|
||||
_ = holder
|
||||
return nil, "", err
|
||||
}
|
||||
asnresolve.PolitePause()
|
||||
holder, _ := asnresolve.ASHolderName(ctx, hc, asn)
|
||||
|
||||
holder := <-holderCh
|
||||
if st != nil {
|
||||
strs := make([]string, len(pfxs))
|
||||
for i, p := range pfxs {
|
||||
@@ -57,3 +72,55 @@ func resolveASNForEntry(ctx context.Context, st store.Backend, hc *http.Client,
|
||||
}
|
||||
return pfxs, holder, nil
|
||||
}
|
||||
|
||||
// startASNHolderFetch launches the holder lookup concurrently. The returned buffered
|
||||
// channel always yields exactly one value, so callers may abandon it without leaking.
|
||||
func startASNHolderFetch(ctx context.Context, hc *http.Client, st store.Backend, asn int64, prevHolder string) <-chan string {
|
||||
ch := make(chan string, 1)
|
||||
go func() {
|
||||
if prevHolder != "" && holderStillFresh(st, asn, prevHolder) {
|
||||
ch <- prevHolder
|
||||
return
|
||||
}
|
||||
holder, err := asnresolve.ASHolderName(ctx, hc, asn)
|
||||
if err != nil || strings.TrimSpace(holder) == "" {
|
||||
ch <- prevHolder
|
||||
return
|
||||
}
|
||||
ch <- strings.TrimSpace(holder)
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
// holderStillFresh reports whether the cached holder name is within its own (long) TTL.
|
||||
func holderStillFresh(st store.Backend, asn int64, prevHolder string) bool {
|
||||
if st == nil {
|
||||
return false
|
||||
}
|
||||
ent, ok, err := st.GetASNPrefixCache(asn)
|
||||
return err == nil && ok && ent != nil && ent.Holder == prevHolder && time.Since(ent.FetchedAt) < asnHolderTTL()
|
||||
}
|
||||
|
||||
func parseASNCachePrefixes(raw []string) []netip.Prefix {
|
||||
out := make([]netip.Prefix, 0, len(raw))
|
||||
for _, p := range raw {
|
||||
pfx, perr := netip.ParsePrefix(strings.TrimSpace(p))
|
||||
if perr != nil {
|
||||
continue
|
||||
}
|
||||
out = append(out, pfx.Masked())
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func parseCachedASNCachedPrefixes(raw []string) []netip.Prefix {
|
||||
out := make([]netip.Prefix, 0, len(raw))
|
||||
for _, p := range raw {
|
||||
pfx, perr := netip.ParsePrefix(strings.TrimSpace(p))
|
||||
if perr != nil {
|
||||
continue
|
||||
}
|
||||
out = append(out, pfx.Masked())
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user