七爪源码:在 Go 中使用缓存的最简单方法

使用 Kubernetes 的 client-go 包

七爪源码:在 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 条评论) “”
   
验证码:

相关文章

推荐文章