...

Source file src/github.com/cybertec-postgresql/pgwatch/v3/internal/reaper/cache.go

Documentation: github.com/cybertec-postgresql/pgwatch/v3/internal/reaper

     1  package reaper
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/cybertec-postgresql/pgwatch/v3/internal/metrics"
    10  	"github.com/cybertec-postgresql/pgwatch/v3/internal/sources"
    11  )
    12  
    13  var monitoredDbCache map[string]*sources.SourceConn
    14  var monitoredDbCacheLock sync.RWMutex
    15  
    16  var lastSQLFetchError sync.Map
    17  
    18  func UpdateMonitoredDBCache(data sources.SourceConns) {
    19  	monitoredDbCacheNew := make(map[string]*sources.SourceConn)
    20  	for _, row := range data {
    21  		monitoredDbCacheNew[row.Name] = row
    22  	}
    23  	monitoredDbCacheLock.Lock()
    24  	monitoredDbCache = monitoredDbCacheNew
    25  	monitoredDbCacheLock.Unlock()
    26  }
    27  
    28  func GetMonitoredDatabaseByUniqueName(ctx context.Context, name string) (*sources.SourceConn, error) {
    29  	if ctx.Err() != nil {
    30  		return nil, ctx.Err()
    31  	}
    32  	monitoredDbCacheLock.RLock()
    33  	defer monitoredDbCacheLock.RUnlock()
    34  	md, exists := monitoredDbCache[name]
    35  	if !exists || md == nil {
    36  		return nil, fmt.Errorf("database %s not found in cache", name)
    37  	}
    38  	return md, nil
    39  }
    40  
    41  type InstanceMetricCache struct {
    42  	cache map[string](metrics.Measurements) // [dbUnique+metric]lastly_fetched_data
    43  	sync.RWMutex
    44  }
    45  
    46  func NewInstanceMetricCache() *InstanceMetricCache {
    47  	return &InstanceMetricCache{
    48  		cache: make(map[string](metrics.Measurements)),
    49  	}
    50  }
    51  
    52  func (imc *InstanceMetricCache) Get(key string, age time.Duration) metrics.Measurements {
    53  	if key == "" {
    54  		return nil
    55  	}
    56  	imc.RLock()
    57  	defer imc.RUnlock()
    58  	instanceMetricEpochNs := (imc.cache[key]).GetEpoch()
    59  
    60  	if time.Now().UnixNano()-instanceMetricEpochNs > age.Nanoseconds() {
    61  		return nil
    62  	}
    63  	instanceMetricData, ok := imc.cache[key]
    64  	if !ok {
    65  		return nil
    66  	}
    67  	return instanceMetricData.DeepCopy()
    68  }
    69  
    70  func (imc *InstanceMetricCache) Put(key string, data metrics.Measurements) {
    71  	if len(data) == 0 || key == "" {
    72  		return
    73  	}
    74  	imc.Lock()
    75  	defer imc.Unlock()
    76  	m := data.DeepCopy()
    77  	if !m.IsEpochSet() {
    78  		m.Touch()
    79  	}
    80  	imc.cache[key] = m
    81  }
    82