-
Notifications
You must be signed in to change notification settings - Fork 7
/
cache.go
98 lines (78 loc) · 1.86 KB
/
cache.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package portal
import (
"context"
"fmt"
"sync"
"golang.org/x/sync/singleflight"
)
type Cacher interface {
Set(ctx context.Context, key interface{}, value interface{}) error
Get(ctx context.Context, key interface{}) (interface{}, error)
}
type ErrNil struct{}
func (e *ErrNil) Error() string {
return "portal cache key not found."
}
type MapCache struct {
c sync.Map
}
func newMapCache() *MapCache {
return &MapCache{}
}
var _ Cacher = (*MapCache)(nil)
func (m *MapCache) Set(_ context.Context, key, value interface{}) error {
m.c.Store(key, value)
return nil
}
func (m *MapCache) Get(_ context.Context, key interface{}) (interface{}, error) {
if v, ok := m.c.Load(key); ok {
return v, nil
}
return nil, &ErrNil{}
}
const (
cacheKeyTem = "%s#%s#%s"
)
var (
DefaultCache = newMapCache()
portalCache Cacher
isCacheDisabled = false
)
// SetCache enable cache strategy
func SetCache(c Cacher) {
if c == nil {
isCacheDisabled = true
return
}
isCacheDisabled = false
portalCache = c
}
// genCacheKey generate cache key
// rules: ReceiverName#MethodName#cacheID
// eg. meth:GetName UserSchema#GetName#0xc000498150,
// attr:Name UserModel#Name#0xc000498150
func genCacheKey(ctx context.Context, receiver interface{}, cacheObj interface{}, methodName string) *string {
cacheID := defaultCacheID(cacheObj)
ck := fmt.Sprintf(cacheKeyTem, structName(receiver), methodName, cacheID)
return &ck
}
// defaultCacheID is the addr of src struct
func defaultCacheID(cacheObj interface{}) string {
return fmt.Sprintf("%p", cacheObj)
}
type cachable interface {
PortalDisableCache() bool
}
type cacheGroup struct {
cache Cacher
g *singleflight.Group
}
func newCacheGroup(cache Cacher) *cacheGroup {
return &cacheGroup{
cache: cache,
g: &singleflight.Group{},
}
}
func (cg *cacheGroup) valid() bool {
return portalCache != nil && cg.cache != nil
}