You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
2.5 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package lockdo
import (
"context"
"joybuywork/internal/app"
"joybuywork/internal/consts/ckey"
"joybuywork/proto/go_proto/workerr"
"errors"
"math/rand"
"time"
grds "github.com/go-redis/redis/v8"
)
func Int64(ctx context.Context, key string, find func() (num int64, err error)) (num int64, err error) {
num, err = app.Redis.Cache.Get(ctx, key).Int64()
if !errors.Is(err, grds.Nil) {
if err != nil {
return
}
return num, nil
}
lc := app.NewFollower(ctx, ckey.ForLock(key)).Lock()
defer lc.Release()
if lc.Error() != nil {
err = workerr.BusyError
return
}
num, err = app.Redis.Cache.Get(ctx, key).Int64()
if !errors.Is(err, grds.Nil) {
if err != nil {
return
}
return num, nil
}
num, err = find()
if err != nil {
return
}
app.Redis.Cache.IncrBy(ctx, key, num)
app.Redis.Cache.Expire(ctx, key, Rand2HourExp())
return
}
func Bytes(ctx context.Context, key string, find func() (data []byte, err error)) (data []byte, err error) {
data, err = app.Redis.Cache.Get(ctx, key).Bytes()
if !errors.Is(err, grds.Nil) {
if err != nil {
return
}
return data, nil
}
lc := app.NewFollower(ctx, ckey.ForLock(key)).Lock()
defer lc.Release()
if lc.Error() != nil {
err = workerr.BusyError
return
}
data, err = app.Redis.Cache.Get(ctx, key).Bytes()
if !errors.Is(err, grds.Nil) {
if err != nil {
return
}
return data, nil
}
data, err = find()
if err != nil {
return
}
app.Redis.Cache.Set(ctx, key, data, Rand2HourExp())
return
}
// ExistDo Key如果存在就返回,不存在就锁住做一些操作
func ExistDo(ctx context.Context, key string, fn func(exist bool) (err error)) (err error) {
exist, err := app.Redis.Exists(ctx, key)
if err != nil {
return
}
if exist {
return fn(true)
}
lc := app.NewFollower(ctx, ckey.ForLock(key)).Lock()
defer lc.Release()
if lc.Error() != nil {
err = workerr.BusyError
return
}
exist, err = app.Redis.Exists(ctx, key)
if err != nil {
return
}
return fn(exist)
}
func FindNilDo(ctx context.Context, key string, find func() (none bool, err error), create func() (err error)) (err error) {
none, err := find()
if err != nil {
return
}
if !none {
return
}
lc := app.NewFollower(ctx, ckey.ForLock(key)).Lock()
defer lc.Release()
if lc.Error() != nil {
err = workerr.BusyError
return
}
none, err = find()
if err != nil {
return
}
if !none {
return
}
return create()
}
func Rand2HourExp() time.Duration {
return time.Duration(rand.Intn(60)+60) * time.Minute
}