mc.extra.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. package dao
  2. import (
  3. "context"
  4. "go-common/app/service/main/ugcpay-rank/internal/conf"
  5. "go-common/library/cache/memcache"
  6. )
  7. // CASCacheElecPrepRank cas的方式存储预备榜单,防止分布式脏写
  8. func (d *Dao) CASCacheElecPrepRank(c context.Context, val interface{}, rawItem *memcache.Item) (ok bool, err error) {
  9. var (
  10. conn = d.mc.Get(c)
  11. )
  12. defer conn.Close()
  13. rawItem.Object = val
  14. rawItem.Expiration = conf.Conf.CacheTTL.ElecPrepAVRankTTL
  15. rawItem.Flags = memcache.FlagProtobuf
  16. if err = conn.CompareAndSwap(rawItem); err != nil {
  17. if err == memcache.ErrCASConflict { // CAS冲突, 则返回ok == false, 准备重试
  18. err = nil
  19. return
  20. }
  21. if err == memcache.ErrNotStored { // 如果CAS中恰好失效,尝试Add
  22. if err = conn.Add(rawItem); err != nil {
  23. if err == memcache.ErrNotStored { // 在Add时恰好又被其他实例Add过, 则返回ok == false, 准备重试
  24. err = nil
  25. return
  26. }
  27. return // 在Add时发生未知错误
  28. }
  29. }
  30. return // 在CAS时发生未知错误
  31. }
  32. ok = true
  33. return
  34. }