emahiro/b.log

日々の勉強の記録とか育児の記録とか。

appengineのmemcacheを使う

GAEではmemcache一択

appengineのmemcacheパッケージを使ってみました。

リファレンスはこちら

https://cloud.google.com/appengine/docs/standard/go/memcache/reference

goでキャッシュを扱うときに最初 go-cache を使おうと思っていたのだけれど、GAEでキャッシュを使うときはmemcacheが標準のパッケージでついているのでこれを使うと簡単に実装できることを知る。

go-cache https://github.com/patrickmn/go-cache

実装方法

キャッシュなので、

  • キャッシュを取得する。
  • キャッシュがexpiredを過ぎていれば新しくキャッシュをセットする

の2通り

sampleコード

import (
  "encoding/json"
  "google.golang.org/appengine/memcache"
  "google.golang.org/appengine"
)

var (
  cacheKey := "KEY"
  casheExpTime := 60 // seconds
)

type Data struct{
  ID   int
  Name string
}

func CacheProcess(r *http.Request){
  ctx := appengie.NewContext(r)
  item, err := memcache.Get(ctx, cacheKey)
  if err != nil {
    // cacheを取得するときのエラー
  }
  
  if item != nil {
    // cacheが存在する時
    fmt.Fprintf("memcache key: %v", item.Key)
    fmt.Fprintf("memcache value: %v", item.Value)
    
    // cacheのValueの中身を取り出す。Valueは[]byte型
    data := &Data{}
    err := json.Unmarshal(item.Value, data)
    if err != nil {
      // jsonをunmarschalした時のエラー
    }
    
  } else {
      // cacheが存在しない時
      data := &Data{
        ID:   1,
        Name: "emahiro"
      }
     
      // dataを[]byte型に変換
      byte, err := json.Marshal(data)
      if err != nil{
        // dataをbyteにMarshalするときのエラー
      }
     
      // cacheをセットする
      i := &memcache.Item{
        Key:        cacheKey,
        Value:      byte
        Expiration: time.Duration(cacheExpTime) * time.Seconds // time.Duration(ns) 型
      }
     
      err := memcache.Set(ctx, i)
      if err != nil {
        // cacheをSetする時のエラー
      }
  }
}

Cacheを登録するときにその値を memcache.Item 型に変換することと、itemの Valueプロパティは[]byte型であるというところに注意すればかなり簡単にキャッシュを実装できます。