77 "runtime"
88 "strings"
99 "sync"
10+ "sync/atomic"
1011 "time"
1112
1213 "github.com/nelkinda/health-go"
2526 cftimeout time.Duration
2627 gql * GraphQL
2728 log = logrus .New ()
29+
30+ // kvNamespaceCache stores accountID -> namespaceID -> name.
31+ // Atomically replaced by refreshKVNamespaceCache, read by getKVNamespaceMap.
32+ kvNamespaceCache atomic.Pointer [map [string ]map [string ]string ]
2833)
2934
3035// var (
@@ -151,6 +156,30 @@ func fetchMetrics(deniedMetricsSet MetricsSet) {
151156 wg .Wait ()
152157}
153158
159+ func refreshKVNamespaceCache () {
160+ accounts := fetchAccounts ()
161+ newCache := make (map [string ]map [string ]string , len (accounts ))
162+ for _ , a := range accounts {
163+ nsMap , err := fetchKVNamespaces (a .ID )
164+ if err != nil {
165+ log .Warnf ("failed to refresh KV namespace cache for account %s: %v" , a .ID , err )
166+ continue
167+ }
168+ newCache [a .ID ] = nsMap
169+ }
170+
171+ kvNamespaceCache .Store (& newCache )
172+ log .Info ("KV namespace cache refreshed" )
173+ }
174+
175+ func getKVNamespaceMap (accountID string ) map [string ]string {
176+ cache := kvNamespaceCache .Load ()
177+ if cache == nil {
178+ return nil
179+ }
180+ return (* cache )[accountID ]
181+ }
182+
154183func runExporter () {
155184 cfgMetricsPath := viper .GetString ("metrics_path" )
156185
@@ -174,6 +203,14 @@ func runExporter() {
174203 log .Debugf ("Metrics set: %v" , metricsSet )
175204 mustRegisterMetrics (metricsSet )
176205
206+ // Populate KV namespace cache at boot, then refresh every 5 minutes.
207+ refreshKVNamespaceCache ()
208+ go func () {
209+ for range time .NewTicker (5 * time .Minute ).C {
210+ refreshKVNamespaceCache ()
211+ }
212+ }()
213+
177214 scrapeInterval := time .Duration (viper .GetInt ("scrape_interval" )) * time .Second
178215 log .Info ("Scrape interval set to " , scrapeInterval )
179216
0 commit comments