Просмотр исходного кода

Merge pull request #221 from kubecost/niko-caching

Flush cache when custom pricing changes
Niko Kovacevic 6 лет назад
Родитель
Сommit
07a9342ea1
1 измененных файлов с 43 добавлено и 0 удалено
  1. 43 0
      costmodel/router.go

+ 43 - 0
costmodel/router.go

@@ -65,6 +65,7 @@ type Accesses struct {
 	AggregateCache                *cache.Cache
 	CostDataCache                 *cache.Cache
 	OutOfClusterCache             *cache.Cache
+	SettingsCache                 *cache.Cache
 }
 
 type DataEnvelope struct {
@@ -343,6 +344,41 @@ func (a *Accesses) ClusterCostsOverTime(w http.ResponseWriter, r *http.Request,
 	w.Write(wrapData(data, err))
 }
 
+func (a *Accesses) CustomPricingHasChanged() bool {
+	customPricing, err := a.Cloud.GetConfig()
+	if err != nil || customPricing == nil {
+		klog.Errorf("error accessing cloud provider configuration: %s", err)
+		return false
+	}
+
+	// describe parameters by which we determine whether or not custom
+	// pricing settings have changed
+	encodeCustomPricing := func(cp *costAnalyzerCloud.CustomPricing) string {
+		return fmt.Sprintf("%s:%s:%s:%s:%s:%s:%s:%s", cp.CustomPricesEnabled, cp.CPU, cp.SpotCPU,
+			cp.RAM, cp.SpotRAM, cp.GPU, cp.Storage, cp.CurrencyCode)
+	}
+
+	// compare cached custom pricing parameters with current values
+	cpStr := encodeCustomPricing(customPricing)
+	cpStrCached := ""
+	val, found := a.SettingsCache.Get("customPricing")
+	if found {
+		ok := false
+		cpStrCached, ok = val.(string)
+		if !ok {
+			klog.Errorf("caching error: failed to cast custom pricing to string")
+		}
+	}
+	if cpStr == cpStrCached {
+		return false
+	}
+
+	// cache new custom pricing settings
+	a.SettingsCache.Set("customPricing", cpStr, cache.DefaultExpiration)
+
+	return true
+}
+
 // AggregateCostModel handles HTTP requests to the aggregated cost model API, which can be parametrized
 // by time period using window and offset, aggregation field and subfield (e.g. grouping by label.app
 // using aggregation=label, aggregationSubfield=app), and filtered by namespace and cluster.
@@ -404,6 +440,11 @@ func (a *Accesses) AggregateCostModel(w http.ResponseWriter, r *http.Request, ps
 		return
 	}
 
+	// if custom pricing has changed, then clear the cache and recompute data
+	if a.CustomPricingHasChanged() {
+		clearCache = true
+	}
+
 	// clear cache prior to checking the cache so that a clearCache=true
 	// request always returns a freshly computed value
 	if clearCache {
@@ -1163,6 +1204,7 @@ func init() {
 	aggregateCache := cache.New(time.Minute*5, time.Minute*10)
 	costDataCache := cache.New(time.Minute*5, time.Minute*10)
 	outOfClusterCache := cache.New(time.Minute*5, time.Minute*10)
+	settingsCache := cache.New(cache.NoExpiration, cache.NoExpiration)
 
 	A = Accesses{
 		PrometheusClient:              promCli,
@@ -1185,6 +1227,7 @@ func init() {
 		AggregateCache:                aggregateCache,
 		CostDataCache:                 costDataCache,
 		OutOfClusterCache:             outOfClusterCache,
+		SettingsCache:                 settingsCache,
 	}
 
 	remoteEnabled := os.Getenv(remoteEnabled)