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