lock.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package dao
  2. import (
  3. "context"
  4. "fmt"
  5. "go-common/library/cache/memcache"
  6. "go-common/library/log"
  7. "go-common/library/stat/prom"
  8. )
  9. func (d *Dao) Lock(c context.Context, key string, val string) (err error) {
  10. if val == "" {
  11. return
  12. }
  13. conn := d.mc.Get(c)
  14. defer conn.Close()
  15. obj := &struct {
  16. Value string
  17. }{
  18. Value: val,
  19. }
  20. item := &memcache.Item{Key: key, Object: obj, Expiration: d.cacheTTL.LockTTL, Flags: memcache.FlagJSON}
  21. if err = conn.Add(item); err != nil {
  22. prom.BusinessErrCount.Incr("mc:Lock")
  23. log.Errorv(c, log.KV("Lock", fmt.Sprintf("%+v", err)), log.KV("key", key))
  24. return
  25. }
  26. return
  27. }
  28. // no thread-safe, but it's works.
  29. // bad case of unlocking:
  30. // 1, process-a gets lock
  31. // 2, lock expires
  32. // 3, process-b gets lock
  33. // 4, process-a releases lock
  34. func (d *Dao) Unlock(c context.Context, key string, val string) (err error) {
  35. conn := d.mc.Get(c)
  36. defer conn.Close()
  37. reply, err := conn.Get(key)
  38. if err != nil {
  39. if err == memcache.ErrNotFound {
  40. err = nil
  41. return
  42. }
  43. prom.BusinessErrCount.Incr("mc:Unlock")
  44. log.Errorv(c, log.KV("Unlock", fmt.Sprintf("%+v", err)), log.KV("key", key))
  45. return
  46. }
  47. res := &struct {
  48. Value string
  49. }{}
  50. err = conn.Scan(reply, &res)
  51. if err != nil {
  52. prom.BusinessErrCount.Incr("mc:Unlock")
  53. log.Errorv(c, log.KV("Unlock", fmt.Sprintf("%+v", err)), log.KV("key", key))
  54. return
  55. }
  56. if res.Value != val {
  57. return nil
  58. }
  59. if err = conn.Delete(key); err != nil {
  60. if err == memcache.ErrNotFound {
  61. err = nil
  62. return
  63. }
  64. prom.BusinessErrCount.Incr("mc:Unlock")
  65. log.Errorv(c, log.KV("Unlock", fmt.Sprintf("%+v", err)), log.KV("key", key))
  66. return
  67. }
  68. return
  69. }