forked from bluesky-social/indigo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcaching.go
81 lines (66 loc) · 1.6 KB
/
caching.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package plc
import (
"context"
"time"
"github.com/bluesky-social/indigo/did"
arc "github.com/hashicorp/golang-lru/arc/v2"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
)
type CachingDidResolver struct {
res did.Resolver
maxAge time.Duration
cache *arc.ARCCache[string, *cachedDoc]
}
type cachedDoc struct {
cachedAt time.Time
doc *did.Document
}
func NewCachingDidResolver(res did.Resolver, maxAge time.Duration, size int) *CachingDidResolver {
c, err := arc.NewARC[string, *cachedDoc](size)
if err != nil {
panic(err)
}
return &CachingDidResolver{
res: res,
cache: c,
maxAge: maxAge,
}
}
func (r *CachingDidResolver) FlushCacheFor(didstr string) {
r.cache.Remove(didstr)
}
func (r *CachingDidResolver) tryCache(did string) (*did.Document, bool) {
cd, ok := r.cache.Get(did)
if !ok {
return nil, false
}
if time.Since(cd.cachedAt) > r.maxAge {
return nil, false
}
return cd.doc, true
}
func (r *CachingDidResolver) putCache(did string, doc *did.Document) {
r.cache.Add(did, &cachedDoc{
doc: doc,
cachedAt: time.Now(),
})
}
func (r *CachingDidResolver) GetDocument(ctx context.Context, didstr string) (*did.Document, error) {
ctx, span := otel.Tracer("cacheResolver").Start(ctx, "getDocument")
defer span.End()
doc, ok := r.tryCache(didstr)
if ok {
span.SetAttributes(attribute.Bool("cache", true))
cacheHitsTotal.Inc()
return doc, nil
}
cacheMissesTotal.Inc()
span.SetAttributes(attribute.Bool("cache", false))
doc, err := r.res.GetDocument(ctx, didstr)
if err != nil {
return nil, err
}
r.putCache(didstr, doc)
return doc, nil
}