Categorygithub.com/liyanbing/go-cache
modulepackage
1.0.3
Repository: https://github.com/liyanbing/go-cache.git
Documentation: pkg.go.dev

# README

go-cache
在具体的获取数据操作(fetcher)前加一层缓存操作

go-cache

  • 1、先根据key从cache中获取数据,如果不存在则从fetcher中获取数据(并发调用时只会有一个请求会调用fetcher,其他请求会复用这个请求返回的数据)

  • 2、从fetcher获取到数据之后然后存储到cache中,然后返回从fetcher获取到的对象

  • 3、如果cache中存在数据,则decode进model对象中返回(注意这时候返回的是model的指针)

tips

注意:如果对象在缓存中存在则一定返回的是对象指针,如果不存在返回的是fetcher返回的数据(为了统一fetcher最好也返回对象的指针)

安装

go get github.com/liyanbing/go-cache

使用

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/golang/protobuf/proto"

	redis "github.com/go-redis/redis/v8"
	go_cache "github.com/liyanbing/go-cache"
	redis_cacher "github.com/liyanbing/go-cache/cacher/redis"
)

type User struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
	Id   uint64 `json:"id"`
}

func main() {
	cache := redis_cacher.NewRedisCache(redis.NewClient(&redis.Options{
		Addr: "127.0.0.1:6379",
		DB:   0,
	}))

	// 1、 json
	temp, err := go_cache.FetchWithJson(context.Background(), cache, "json1", func() (interface{}, time.Duration, error) {
		return &User{
			Name: "peter",
			Age:  23,
			Id:   123123,
		}, time.Hour, nil
	}, User{})
	if err != nil {
		log.Fatal(err)
	}
	ret := temp.(*User)
	fmt.Println("json:", *ret)

	// 2、json2
	temp, err = go_cache.FetchWithJson(context.Background(), cache, "json2", func() (interface{}, time.Duration, error) {
		// 这里返回的不是指针
		return User{
			Name: "peter",
			Age:  23,
			Id:   123123,
		}, time.Hour, nil
	}, User{})
	if err != nil {
		log.Fatal(err)
	}

	// 这里因为fetcher中返回的是非对象指针,但是从缓存中获取到数据之后返回的是对象指针所以需要判断
	switch temp.(type) {
	case *User:
		ret = temp.(*User)
	case User:
		ret1 := temp.(User)
		ret = &ret1
	}
	fmt.Println("json:", *ret)

	// 3、string
	str, err := go_cache.FetchWithString(context.Background(), cache, "string", func() (interface{}, time.Duration, error) {
		return "golang", time.Hour, nil
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(str)

	// 4、protobuf
	pro, err := go_cache.FetchWithProtobuf(context.Background(), cache, "protobuf", func() (interface{}, time.Duration, error) {
		return &TempModelPb{
			IsMember: true,
			ExpireAt: 19999,
		}, time.Hour, nil
	}, new(TempModelPb))
	if err != nil {
		log.Fatal(err)
	}
	proRet := pro.(*TempModelPb)
	fmt.Println(*proRet)

	// 5、number
	num, err := go_cache.FetchWithNumber(context.Background(), cache, "number", func() (interface{}, time.Duration, error) {
		return int64(100), time.Hour, nil
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(num)

	// 6、number
	// 也可以通过go_cache.WithNoUseCache来表示不使用缓存直接从fetcher中获取数据,这时候会顺便更新缓存数据
	ctx := go_cache.WithNoUseCache(context.Background())
	num, err = go_cache.FetchWithNumber(ctx, cache, "number", func() (interface{}, time.Duration, error) {
		return 300.02, time.Hour, nil
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(num)

	// 7、array1
	arr, err := go_cache.FetchWithArray(context.Background(), cache, "array", func() (interface{}, time.Duration, error) {
		return []*User{
			{
				Name: "golang",
				Age:  5,
			},
			{
				Name: "java",
				Age:  10,
			},
		}, time.Hour, nil
	}, []*User{})
	if err != nil {
		log.Fatal(err)
	}
	arrRet := arr.([]*User)
	fmt.Println(arrRet)

	// 7、array2
	arr1, err := go_cache.FetchWithArray(context.Background(), cache, "array2", func() (interface{}, time.Duration, error) {
		return []*User{
			{
				Name: "golang",
				Age:  5,
			},
			{
				Name: "java",
				Age:  10,
			},
		}, time.Hour, nil
	}, []User{})
	if err != nil {
		log.Fatal(err)
	}
	arr1Ret := arr1.([]User)
	fmt.Println(arr1Ret)

	// 8、array3
	type Temp struct {
		Users []*User
	}

	arr3, err := go_cache.FetchWithJson(context.Background(), cache, "array3", func() (interface{}, time.Duration, error) {
		return &Temp{
			Users: []*User{
				{
					Name: "golang",
					Age:  5,
				},
				{
					Name: "java",
					Age:  10,
				},
			},
		}, time.Hour, nil
	}, new(Temp))
	if err != nil {
		log.Fatal(err)
	}
	arr3Ret := arr3.(*Temp)
	fmt.Println(*arr3Ret)
}

type TempModelPb struct {
	IsMember bool  `protobuf:"varint,1,opt,name=is_member,json=isMember" json:"is_member,omitempty"`
	ExpireAt int64 `protobuf:"varint,2,opt,name=expire_at,json=expireAt" json:"expire_at,omitempty"`
}

func (m *TempModelPb) Reset()                    { *m = TempModelPb{} }
func (m *TempModelPb) String() string            { return proto.CompactTextString(m) }
func (*TempModelPb) ProtoMessage()               {}
func (*TempModelPb) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }

var fileDescriptor0 = []byte{
	// 582 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdb, 0x6e, 0xda, 0x40,
	0x10, 0x0d, 0xa1, 0x09, 0x64, 0x12, 0x52, 0xb3, 0xa5, 0x29, 0x71, 0x5a, 0x35, 0xf2, 0x53, 0x54,
	0xb5, 0xa8, 0x4d, 0xfb, 0x03, 0x10, 0x22, 0x44, 0xa5, 0xa8, 0xc8, 0x20, 0x55, 0xea, 0x0b, 0x32,
	0xde, 0x11, 0x59, 0x09, 0xbc, 0x96, 0xbd, 0x46, 0xe1, 0xdb, 0xfa, 0x73, 0xd5, 0xae, 0xd7, 0x31,
	0xbe, 0x95, 0xf6, 0x8d, 0x99, 0x73, 0xe6, 0xcc, 0xce, 0xc5, 0x03, 0x9c, 0xf9, 0x62, 0xc9, 0x57,
	0xb4, 0xe7, 0x07, 0x5c, 0x70, 0x72, 0x1c, 0x5b, 0xd6, 0x17, 0xe8, 0x4c, 0x23, 0xd7, 0x45, 0xa4,
	0x83, 0x68, 0xfb, 0x80, 0xeb, 0x05, 0x06, 0xfd, 0x60, 0x19, 0x92, 0x4b, 0x68, 0x3a, 0x11, 0x65,
	0x62, 0xce, 0x68, 0xb7, 0x76, 0x5d, 0xbb, 0x79, 0x61, 0x37, 0x94, 0x3d, 0xa6, 0xd6, 0x45, 0x31,
	0xc4, 0xc6, 0xd0, 0xb7, 0x7a, 0xd0, 0x1e, 0xa1, 0x18, 0x7b, 0x1b, 0x26, 0xf0, 0x8e, 0x53, 0x4c,
	0x74, 0x16, 0xd1, 0x16, 0x83, 0x1d, 0x1d, 0x65, 0x8f, 0xa9, 0xf5, 0x2d, 0xc7, 0x97, 0x22, 0xe4,
	0x3d, 0x9c, 0x32, 0xe5, 0x99, 0xbb, 0x9c, 0x62, 0xf7, 0xf0, 0xba, 0x76, 0x73, 0x62, 0x03, 0x7b,
	0x26, 0x59, 0x13, 0x20, 0x03, 0xe6, 0xd1, 0x7f, 0x4e, 0xb3, 0x5f, 0xb1, 0x93, 0x57, 0x54, 0xd5,
	0x7c, 0x86, 0x57, 0x23, 0x14, 0x71, 0x79, 0x53, 0xe1, 0x88, 0x28, 0xdc, 0x57, 0xcf, 0x8f, 0x42,
	0x84, 0xaa, 0xe8, 0x0a, 0x4e, 0x58, 0x38, 0x5f, 0x2b, 0xb7, 0x0a, 0x69, 0xda, 0x4d, 0x16, 0xc6,
	0x34, 0x09, 0xe2, 0x93, 0xcf, 0x02, 0x9c, 0x3b, 0x42, 0x3d, 0xad, 0x6e, 0x37, 0x63, 0x47, 0x5f,
	0x58, 0x9f, 0xc0, 0x98, 0x04, 0x58, 0x98, 0x4b, 0x55, 0xfe, 0x1c, 0x5d, 0x25, 0xff, 0xcb, 0x18,
	0x7f, 0x01, 0xf9, 0xe9, 0xac, 0x56, 0x28, 0xee, 0x9f, 0xdc, 0x47, 0xc7, 0x5b, 0xc6, 0x8d, 0xfc,
	0x08, 0x75, 0xb1, 0xf5, 0x15, 0xf7, 0xfc, 0xd6, 0xec, 0xe9, 0x9d, 0xc9, 0x12, 0x67, 0x5b, 0x1f,
	0x6d, 0x49, 0x23, 0x17, 0x70, 0x1c, 0xf2, 0x28, 0x70, 0x51, 0xbf, 0x5d, 0x5b, 0xb2, 0xa5, 0xd9,
	0x90, 0x64, 0x41, 0x62, 0xef, 0x10, 0x7d, 0x1e, 0x32, 0xb1, 0xaf, 0xa0, 0xfb, 0x1c, 0x5f, 0x55,
	0xd4, 0x81, 0x23, 0x97, 0x33, 0x2f, 0x54, 0xe4, 0xba, 0x1d, 0x1b, 0xc4, 0x84, 0x26, 0x65, 0xce,
	0x9a, 0x7b, 0x34, 0x4c, 0xda, 0x98, 0xd8, 0xd6, 0x10, 0x5e, 0x4f, 0xa2, 0xc0, 0x7d, 0x74, 0x42,
	0x1c, 0x6c, 0x87, 0xb1, 0x37, 0x49, 0xcd, 0x03, 0x9a, 0x49, 0xad, 0xec, 0x31, 0x25, 0x06, 0xd4,
	0xbd, 0x68, 0xad, 0xa5, 0xe4, 0x4f, 0xeb, 0x4d, 0x89, 0x8a, 0xaa, 0xaa, 0x0f, 0x24, 0x05, 0xee,
	0x38, 0xf3, 0xfe, 0x5f, 0xbb, 0x93, 0x97, 0x90, 0xc2, 0x1f, 0x46, 0xf9, 0x26, 0xca, 0xbe, 0x93,
	0x53, 0x68, 0x8c, 0xbd, 0x8d, 0xb3, 0x62, 0xd4, 0x38, 0x20, 0x6d, 0x68, 0x49, 0xfa, 0x8c, 0xeb,
	0x07, 0x19, 0x35, 0xe9, 0xd2, 0xc6, 0x8c, 0x4b, 0xcc, 0x38, 0xbc, 0xfd, 0x7d, 0x04, 0x8d, 0x29,
	0x06, 0x1b, 0xe6, 0x22, 0x19, 0x41, 0x2b, 0xd3, 0x53, 0x72, 0x99, 0x9d, 0xf1, 0xce, 0x68, 0xcc,
	0x72, 0x48, 0x15, 0x7d, 0x40, 0xbe, 0xc3, 0x79, 0xf6, 0x75, 0xa4, 0x62, 0x5b, 0x94, 0x54, 0x05,
	0x96, 0x6a, 0x65, 0xeb, 0x4f, 0xb5, 0x8a, 0xad, 0x35, 0x2b, 0x30, 0xad, 0x35, 0x85, 0x76, 0x61,
	0x4e, 0xe4, 0x5d, 0x31, 0x64, 0x67, 0x11, 0xcc, 0x6a, 0x58, 0x8b, 0x0e, 0xe1, 0x6c, 0xf7, 0xd3,
	0x22, 0xdd, 0xe7, 0x80, 0xdc, 0xf7, 0x69, 0x96, 0x22, 0x5a, 0x65, 0x02, 0x46, 0xfe, 0x70, 0x92,
	0xb7, 0x09, 0xbf, 0xec, 0x0a, 0x9b, 0x95, 0xa8, 0x56, 0x7c, 0x80, 0x97, 0xb9, 0x93, 0x43, 0xae,
	0x92, 0x90, 0x92, 0xeb, 0x65, 0x56, 0x81, 0x5a, 0x6e, 0x04, 0xad, 0xcc, 0x45, 0x4e, 0x97, 0xa3,
	0x70, 0xd8, 0xcd, 0x72, 0x28, 0x1d, 0x68, 0xf6, 0xa4, 0xa6, 0x03, 0x2d, 0x1e, 0x6f, 0xb3, 0x02,
	0x8b, 0xb5, 0x16, 0xc7, 0xea, 0x0f, 0xeb, 0xeb, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x99,
	0xe9, 0x37, 0xc0, 0x06, 0x00, 0x00,
}

# Packages

No description provided by the author
No description provided by the author
No description provided by the author

# Functions

No description provided by the author
批量获取otherKeys的缓存数据,如果缓存中不存在则会通过fetcher获取不存在缓存中的数据,通过fetcher获取到的数据不会加入缓存.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Interfaces

No description provided by the author
No description provided by the author

# Type aliases

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
* * value: 需要存储在缓存中的值 * expiration: value 过期时间 * err:错误 */.