初始化2
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"bj_power_mes/internal/svc"
|
||||
)
|
||||
|
||||
// Service 业务逻辑服务(handler 薄层调用)
|
||||
type Service struct {
|
||||
ctx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func New(s *svc.ServiceContext) *Service {
|
||||
return &Service{ctx: s}
|
||||
}
|
||||
|
||||
// cached 看板缓存:TTL + 防击穿(SETNX 锁),同一 key 同时仅一个打到 DB
|
||||
func (s *Service) cached(ctx context.Context, key string, ttl int, build func() (any, error)) (any, error) {
|
||||
if s.ctx.RedisClient == nil {
|
||||
return build()
|
||||
}
|
||||
if v, err := s.ctx.RedisClient.Get(key); err == nil && v != "" {
|
||||
var out any
|
||||
if json.Unmarshal([]byte(v), &out) == nil {
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
|
||||
lockKey := key + ":lock"
|
||||
ok, _ := s.ctx.RedisClient.SetnxEx(lockKey, "1", 10)
|
||||
if !ok {
|
||||
// 有人正在重建缓存:短暂等待后重读
|
||||
for i := 0; i < 10; i++ {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if v, err := s.ctx.RedisClient.Get(key); err == nil && v != "" {
|
||||
var out any
|
||||
if json.Unmarshal([]byte(v), &out) == nil {
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return build()
|
||||
}
|
||||
defer func() { _, _ = s.ctx.RedisClient.Del(lockKey) }()
|
||||
|
||||
data, err := build()
|
||||
if err == nil {
|
||||
if b, e := json.Marshal(data); e == nil {
|
||||
_ = s.ctx.RedisClient.Setex(key, string(b), ttl)
|
||||
}
|
||||
}
|
||||
return data, err
|
||||
}
|
||||
Reference in New Issue
Block a user