dao.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package block
  2. import (
  3. "context"
  4. "math"
  5. "math/rand"
  6. "time"
  7. "go-common/app/service/main/member/conf"
  8. "go-common/library/cache/memcache"
  9. "go-common/library/database/sql"
  10. "go-common/library/log"
  11. bm "go-common/library/net/http/blademaster"
  12. xtime "go-common/library/time"
  13. "github.com/pkg/errors"
  14. )
  15. type notifyFunc func(context.Context, int64, string) error
  16. // Dao is
  17. type Dao struct {
  18. *cacheTTL
  19. c *conf.Config
  20. mc *memcache.Pool
  21. db *sql.DB
  22. client *bm.Client
  23. NotifyPurgeCache notifyFunc
  24. }
  25. type cacheTTL struct {
  26. UserTTL int32
  27. UserMaxRate float64
  28. UserT float64
  29. }
  30. // New is
  31. func New(conf *conf.Config, db *sql.DB, mc *memcache.Pool, client *bm.Client, notifyFunc notifyFunc) *Dao {
  32. d := &Dao{
  33. c: conf,
  34. mc: mc,
  35. db: db,
  36. client: client,
  37. NotifyPurgeCache: notifyFunc,
  38. }
  39. d.cacheTTL = newCacheTTL(conf.BlockCacheTTL)
  40. return d
  41. }
  42. // BeginTran is
  43. func (d *Dao) BeginTran(c context.Context) (tx *sql.Tx, err error) {
  44. if tx, err = d.db.Begin(c); err != nil {
  45. err = errors.WithStack(err)
  46. }
  47. return
  48. }
  49. func durationToSeconds(expire xtime.Duration) int32 {
  50. return int32(time.Duration(expire) / time.Second)
  51. }
  52. func newCacheTTL(c *conf.BlockCacheTTL) *cacheTTL {
  53. return &cacheTTL{
  54. UserTTL: durationToSeconds(c.UserTTL),
  55. UserMaxRate: c.UserMaxRate,
  56. UserT: c.UserT,
  57. }
  58. }
  59. func (ttl *cacheTTL) mcUserExpire(key string) (sec int32) {
  60. if ttl.UserT == 0.0 {
  61. return ttl.UserTTL
  62. }
  63. // rate = -log(1-x)/t
  64. rate := -math.Log(1-rand.Float64()) / ttl.UserT
  65. if rate <= 1.0 {
  66. return ttl.UserTTL
  67. }
  68. if rate > ttl.UserMaxRate {
  69. rate = ttl.UserMaxRate
  70. }
  71. sec = int32(rate * float64(ttl.UserTTL))
  72. if rate >= 5.0 {
  73. log.Info("mc hotkey : %s, expire rate : %.2f , time : %d", key, rate, sec)
  74. }
  75. return
  76. }
  77. // Close close the resource.
  78. func (d *Dao) Close() {
  79. if d.mc != nil {
  80. d.mc.Close()
  81. }
  82. if d.db != nil {
  83. d.db.Close()
  84. }
  85. }