...
1
2
3
4
5
6
7
8
9
10
11
12 package cache
13
14 import (
15 "sync"
16 "time"
17
18 "github.com/LINBIT/golinstor/client"
19 )
20
21 var (
22 yes = true
23 cacheOpt = &client.ListOpts{Cached: &yes}
24 )
25
26 type Cache interface {
27 apply(c *client.Client)
28 }
29
30
31 func WithCaches(caches ...Cache) client.Option {
32 return func(cl *client.Client) error {
33 for _, ca := range caches {
34 ca.apply(cl)
35 }
36
37 return nil
38 }
39 }
40
41 type cache struct {
42 mu sync.Mutex
43 lastUpdate time.Time
44 cache any
45 }
46
47
48
49 func (c *cache) Invalidate() {
50 c.mu.Lock()
51 c.lastUpdate = time.Time{}
52 c.cache = nil
53 c.mu.Unlock()
54 }
55
56
57
58
59
60
61 func (c *cache) Get(timeout time.Duration, updateFunc func() (any, error)) (any, error) {
62 c.mu.Lock()
63 defer c.mu.Unlock()
64
65 now := time.Now()
66
67 if timeout != 0 && c.lastUpdate.Add(timeout).Before(now) {
68 result, err := updateFunc()
69 if err != nil {
70 return nil, err
71 }
72
73 c.cache = result
74 c.lastUpdate = now
75 }
76
77 return c.cache, nil
78 }
79
80
81
82 func filterNodeAndPoolOpts[T any](items []T, getNodeAndPoolNames func(*T) ([]string, []string), opts ...*client.ListOpts) []T {
83 filterNames := make(map[string]struct{})
84 filterPools := make(map[string]struct{})
85
86 for _, o := range opts {
87 for _, n := range o.Node {
88 filterNames[n] = struct{}{}
89 }
90
91 for _, sp := range o.StoragePool {
92 filterPools[sp] = struct{}{}
93 }
94 }
95
96 var result []T
97
98 outer:
99 for i := range items {
100 nodes, pools := getNodeAndPoolNames(&items[i])
101
102 if len(filterNames) > 0 {
103 for _, nodeName := range nodes {
104 if _, ok := filterNames[nodeName]; !ok {
105 continue outer
106 }
107 }
108 }
109
110 if len(filterPools) > 0 {
111 for _, poolName := range pools {
112 if _, ok := filterPools[poolName]; !ok {
113 continue outer
114 }
115 }
116 }
117
118 result = append(result, items[i])
119 }
120
121 return result
122 }
123
View as plain text