-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathexample_advanced_test.go
129 lines (111 loc) · 3.87 KB
/
example_advanced_test.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package cache_test
import (
"context"
"fmt"
"time"
"github.com/go-redis/redis/v8"
"github.com/vmihailenco/msgpack/v5"
"github.com/viney-shih/go-cache"
)
type Person struct {
FirstName string
LastName string
Age int
}
// Example_cacheAsidePattern demonstrates multi-layered caching and
// multiple prefix keys at the same time.
func Example_cacheAsidePattern() {
tinyLfu := cache.NewTinyLFU(10000)
rds := cache.NewRedis(redis.NewRing(&redis.RingOptions{
Addrs: map[string]string{
"server1": ":6379",
},
}))
cacheF := cache.NewFactory(rds, tinyLfu)
c := cacheF.NewCache([]cache.Setting{
{
Prefix: "teacher",
CacheAttributes: map[cache.Type]cache.Attribute{
cache.SharedCacheType: {TTL: time.Hour},
cache.LocalCacheType: {TTL: 10 * time.Minute},
},
MarshalFunc: msgpack.Marshal,
UnmarshalFunc: msgpack.Unmarshal,
},
{
Prefix: "student",
CacheAttributes: map[cache.Type]cache.Attribute{
cache.SharedCacheType: {TTL: time.Hour},
cache.LocalCacheType: {TTL: 10 * time.Minute},
},
MGetter: func(keys ...string) (interface{}, error) {
// The MGetter is used to generate data when cache missed, and refill the cache automatically..
// You can read from DB or other microservices.
// Assume we read from MySQL according to the key "jacky" and get the value of
// Person{FirstName: "jacky", LastName: "Lin", Age: 38}
// HINT: remember to return as a slice, and the item order needs to consist with the keys in the parameters.
if len(keys) == 1 && keys[0] == "jacky" {
return []Person{{FirstName: "Jacky", LastName: "Lin", Age: 38}}, nil
}
return nil, fmt.Errorf("XD")
},
MarshalFunc: cache.Marshal,
UnmarshalFunc: cache.Unmarshal,
},
})
ctx := context.TODO()
teacher := &Person{}
if err := c.GetByFunc(ctx, "teacher", "jacky", teacher, func() (interface{}, error) {
// The getter is used to generate data when cache missed, and refill the cache automatically..
// You can read from DB or other microservices.
// Assume we read from MySQL according to the key "jacky" and get the value of
// Person{FirstName: "jacky", LastName: "Wang", Age: 83} .
return Person{FirstName: "Jacky", LastName: "Wang", Age: 83}, nil
}); err != nil {
panic("not expected")
}
fmt.Println(teacher) // {FirstName: "Jacky", LastName: "Wang", Age: 83}
student := &Person{}
if err := c.Get(ctx, "student", "jacky", student); err != nil {
panic("not expected")
}
fmt.Println(student) // {FirstName: "Jacky", LastName: "Lin", Age: 38}
// Output:
// &{Jacky Wang 83}
// &{Jacky Lin 38}
}
// Example_pubsubPattern demonstrates how to leverage Pubsub pattern
// to broadcast evictions between distributed systems, and
// make in-memory cache consistency eventually ASAP.
func Example_pubsubPattern() {
tinyLfu := cache.NewTinyLFU(10000)
rds := cache.NewRedis(redis.NewRing(&redis.RingOptions{
Addrs: map[string]string{
"server1": ":6379",
},
}))
cacheF := cache.NewFactory(rds, tinyLfu, cache.WithPubSub(rds))
c := cacheF.NewCache([]cache.Setting{
{
Prefix: "user",
CacheAttributes: map[cache.Type]cache.Attribute{
cache.SharedCacheType: {TTL: time.Hour},
cache.LocalCacheType: {TTL: 10 * time.Minute},
},
},
})
ctx := context.TODO()
user := &Person{}
if err := c.GetByFunc(ctx, "user", "tony", user, func() (interface{}, error) {
// The getter is used to generate data when cache missed, and refill the cache automatically.
// Assume we read from MySQL according to the key "tony" and get the value of
// Person{FirstName: "Tony", LastName: "Stock", Age: 87} .
// At the same time, it will broadcast the eviction about the prefix "user" and the key "tony" to others.
return Person{FirstName: "Tony", LastName: "Stock", Age: 87}, nil
}); err != nil {
panic("not expected")
}
fmt.Println(user) // {FirstName: "Tony", LastName: "Stock", Age: 87}
// Output:
// &{Tony Stock 87}
}