使用 Kubernetes 的 client-go 包
缓存是任何程序中用于快速访问常用数据的重要概念之一。
在本文中,让我们了解如何轻松使用 Kubernetes client-go 包中可用的缓存方法。
首先,让我们考虑一个简单的场景,我们希望将键和值存储在缓存中。
// cacheTTL is the duration of time to hold the key in cache
const cacheTTL = 20 * time.Second
// keyValue contains the fields to store the key and value
type keyValue struct {
key string
value string
}
func main() {
cacheStore := cache.NewTTLStore(cacheKeyFunc, cacheTTL)
}// cacheKeyFunc defines the key function required in TTLStore.
func cacheKeyFunc(obj interface{}) (string, error) {
return obj.(keyValue).key, nil
}在上面的代码片段中,在 main 函数中,我们使用以下内容初始化缓存存储:
cacheKeyFunc:它告诉使用什么作为将用户提供的对象存储在缓存中的键。
cacheTTL:将密钥保存在缓存中的持续时间。
基本初始化完成后,我们现在可以借助以下函数将值存储在缓存中:
func addToCache(cacheStore cache.Store, object keyValue) error {
err := cacheStore.Add(object)
if err != nil {
klog.Errorf("failed to add key value to cache error", err)
return err
}
return nil
}
func fetchFromCache(cacheStore cache.Store, key string) (string, error) {
obj, exists, err := cacheStore.GetByKey(key)
if err != nil {
klog.Errorf("failed to add key value to cache error", err)
return "", err
}
if !exists {
klog.Errorf("object does not exist in the cache")
return "", nil
}
return obj.(keyValue).value, nil
}
func deleteFromCache(cacheStore cache.Store, object keyValue) error {
return cacheStore.Delete(object)
}在上面的代码片段中,我们使用了 cachestore 方法
添加以将值存储在缓存中,GetByKey 从提供的键中获取值,“删除”以从缓存中删除值。
在获取时,我们需要确保我们检查所需键的值是否存在于缓存中,如果它过期或从未添加过,它可能不存在于缓存中。
此外,除了 Add、GetByKey 和 Delete 方法之外,缓存存储还有许多其他方法,如 Get、Update、List 等
最后,main函数看起来是这样的
func main() {
cacheStore := cache.NewTTLStore(cacheKeyFunc, cacheTTL)
testKey := "myKey"
key := keyValue{
key: testKey,
value: "myValue",
}
klog.Infof("adding the key %v to cache", key)
err := addToCache(cacheStore, key)
if err != nil {
klog.Fatalf("failed to add the key %v to cache error %v", key, err)
}
klog.Infof("fetching the value for key: %s from cache", testKey)
value, err := fetchFromCache(cacheStore, "myKey")
if err != nil {
klog.Fatalf("failed to fetch value for key %S from cache error %v", testKey, err)
}
if value == "" {
klog.Fatalf("the value for key %s is empty", testKey)
}
klog.Infof("successfully fetched the value for key %s from cache value: %s", testKey, value)
klog.Infof("deleting the key %s from cache", testKey)
err = deleteFromCache(cacheStore, key)
if err != nil {
klog.Fatalf("failed to delete key %s from cache error %v", testKey, err)
}
}在我们为上述代码添加单元测试之前,我们的工作还没有完全完成。 让我们为 addToCache 和 fetchFromCache 函数添加单元测试。
func TestAddToCache(t *testing.T) {
cacheStore := cache.NewTTLStore(cacheKeyFunc, cacheTTL)
testKey := keyValue{
key: "testKey",
value: "testValue",
}
err := addToCache(cacheStore, testKey)
if err != nil {
t.Fatalf("expecting error to be nil but got err %v", err)
}
}
func TestFetchFromCache(t *testing.T) {
defaultCacheStoreFunc := func() cache.Store {
return cache.NewTTLStore(cacheKeyFunc, cacheTTL)
}
testKey := keyValue{
key: "testKey",
value: "testValue",
}
testCases := []struct {
name string
expectedError error
expectedValue string
keyName string
sleep bool
cacheStore func() cache.Store
}{
{
name: "exists in cache",
expectedValue: "testValue",
keyName: "testKey",
cacheStore: defaultCacheStoreFunc,
},
{
name: "not exists in cache",
expectedValue: "",
keyName: "notTestKey",
cacheStore: defaultCacheStoreFunc,
},
{
name: "key in cache expired",
expectedValue: "",
keyName: "testKey",
cacheStore: func() cache.Store {
return cache.NewTTLStore(cacheKeyFunc, time.Millisecond)
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
gs := NewWithT(t)
cacheStore := tc.cacheStore()
err := addToCache(cacheStore, testKey)
if err != nil {
t.Fatalf("failed to add key to cache error %v", err)
}
if tc.sleep {
time.Sleep(time.Second)
}
value, err := fetchFromCache(cacheStore, keyValue{key: tc.keyName})
if err != nil {
if tc.expectedError != nil {
gs.Expect(err).To(HaveOccurred())
gs.Expect(err.Error()).To(Equal(tc.expectedError.Error()))
} else {
gs.Expect(err).ToNot(HaveOccurred())
}
}
gs.Expect(value).To(Equal(tc.expectedValue))
})
}
}关注七爪网,获取更多APP/小程序/网站源码资源!
| 留言与评论(共有 0 条评论) “” |