summaryrefslogtreecommitdiff
path: root/internal/api/cache.go
diff options
context:
space:
mode:
authorjwijenbergh <jeroenwijenbergh@protonmail.com>2024-03-01 15:25:55 +0100
committerjwijenbergh <jeroenwijenbergh@protonmail.com>2024-03-01 15:25:55 +0100
commit6422ef9bcee312a5e9ab9cd32290b8ea733e016f (patch)
tree6375175e707df59e2d09d4a3641de374649c2d52 /internal/api/cache.go
parentd719e23204bc403c43f61093d080a59d290ff6e6 (diff)
API: Implement a 10 minute well-known endpoint cache
Diffstat (limited to 'internal/api/cache.go')
-rw-r--r--internal/api/cache.go64
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
+}