diff options
| author | jwijenbergh <jeroenwijenbergh@protonmail.com> | 2024-03-01 15:25:55 +0100 |
|---|---|---|
| committer | jwijenbergh <jeroenwijenbergh@protonmail.com> | 2024-03-01 15:25:55 +0100 |
| commit | 6422ef9bcee312a5e9ab9cd32290b8ea733e016f (patch) | |
| tree | 6375175e707df59e2d09d4a3641de374649c2d52 /internal/api/cache.go | |
| parent | d719e23204bc403c43f61093d080a59d290ff6e6 (diff) | |
API: Implement a 10 minute well-known endpoint cache
Diffstat (limited to 'internal/api/cache.go')
| -rw-r--r-- | internal/api/cache.go | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/internal/api/cache.go b/internal/api/cache.go new file mode 100644 index 0000000..2baefc8 --- /dev/null +++ b/internal/api/cache.go @@ -0,0 +1,64 @@ +package api + +import ( + "context" + "sync" + "time" + + "github.com/eduvpn/eduvpn-common/internal/api/endpoints" +) + +// EndpointCache is a struct that caches well-known API endpoints +type EndpointCache struct { + lastUpdate map[string]time.Time + lastEP map[string]*endpoints.Endpoints + mu sync.Mutex +} + +// Get() returns a cached or fresh endpoint cache copy +func (ec *EndpointCache) Get(ctx context.Context, wk string) (*endpoints.Endpoints, error) { + ec.mu.Lock() + defer ec.mu.Unlock() + + // get the last update time + lu := time.Time{} + if v, ok := ec.lastUpdate[wk]; ok { + lu = v + } + + // if not 10 minutes have passed, return cached copy + if !lu.IsZero() && !time.Now().After(lu.Add(10*time.Minute)) { + v, ok := ec.lastEP[wk] + if ok { + return v, nil + } + } + + // get fresh API endpoints + ep, err := getEndpoints(ctx, wk) + if err != nil { + return nil, err + } + + // update endpoints + ec.lastUpdate[wk] = time.Now() + ec.lastEP[wk] = ep + + return ep, nil +} + +var ( + epCache *EndpointCache + epCacheOnce sync.Once +) + +func GetEndpointCache() *EndpointCache { + epCacheOnce.Do(func() { + epCache = &EndpointCache{ + lastUpdate: make(map[string]time.Time), + lastEP: make(map[string]*endpoints.Endpoints), + } + }) + + return epCache +} |
