/
set.go
99 lines (90 loc) · 2.31 KB
/
set.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
99
package cache
import (
"context"
"fmt"
"time"
)
// Set caches the item.
func (self *Cache) Set(ctx context.Context, items ...Item) error {
if len(items) == 1 {
_, err := self.set(ctx, &items[0])
return err
}
_, err := self.setItems(ctx, items)
return err
}
func (self *Cache) set(ctx context.Context, item *Item) ([]byte, error) {
b, err := item.marshal(ctx, self.Marshal)
if err != nil || b == nil {
return nil, err
}
switch {
case self.useLocalCache(item) && self.useRedis():
done := make(chan error)
go func() {
done <- self.redisSet(ctx, item, b, item.ttl(self.DefaultTTL()))
}()
self.localCache.Set(self.ResolveKey(item.Key), b)
err = <-done
case self.useLocalCache(item):
self.localCache.Set(self.ResolveKey(item.Key), b)
case self.useRedis():
err = self.redisSet(ctx, item, b, item.ttl(self.DefaultTTL()))
}
return b, err
}
func (self *Cache) redisSet(ctx context.Context, item *Item, b []byte,
ttl time.Duration,
) error {
err := self.redis.Set(ctx, 1, func(int) (string, []byte, time.Duration) {
return self.ResolveKey(item.Key), b, ttl
})
if err != nil {
return self.redisCacheError(fmt.Errorf("redis set: %w", err))
}
return nil
}
func (self *Cache) setItems(ctx context.Context, items []Item,
) ([][]byte, error) {
bytes, err := self.marshalItems(ctx, items)
if err != nil {
return nil, err
}
useLocal := self.localCache != nil
switch {
case useLocal && self.useRedis():
done := make(chan error)
go func() {
done <- self.redisSetItems(ctx, items, bytes)
}()
self.localSetItems(items, bytes)
err = <-done
case useLocal:
self.localSetItems(items, bytes)
case self.useRedis():
err = self.redisSetItems(ctx, items, bytes)
}
return bytes, err
}
func (self *Cache) localSetItems(items []Item, bytes [][]byte) {
for i := range items {
item := &items[i]
b := bytes[i]
if !item.SkipLocalCache && len(b) > 0 {
self.localCache.Set(self.ResolveKey(item.Key), b)
}
}
}
func (self *Cache) redisSetItems(ctx context.Context, items []Item,
bytes [][]byte,
) error {
err := self.redis.Set(ctx, len(items),
func(i int) (string, []byte, time.Duration) {
item := &items[i]
return self.ResolveKey(item.Key), bytes[i], item.ttl(self.DefaultTTL())
})
if err != nil {
return self.redisCacheError(fmt.Errorf("failed set redis items: %w", err))
}
return nil
}