memcache.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. package dao
  2. import (
  3. "context"
  4. "fmt"
  5. "strconv"
  6. "go-common/app/service/main/member/model"
  7. "go-common/library/cache/memcache"
  8. "go-common/library/log"
  9. "github.com/pkg/errors"
  10. )
  11. const (
  12. _expPrefix = "exp_%d"
  13. _moralPrefix = "moral_%d"
  14. _expExpire = 86400
  15. )
  16. func expKey(mid int64) string {
  17. return fmt.Sprintf(_expPrefix, mid)
  18. }
  19. func moralKey(mid int64) string {
  20. return fmt.Sprintf(_moralPrefix, mid)
  21. }
  22. // pingMC ping memcache.
  23. func (d *Dao) pingMC(c context.Context) (err error) {
  24. conn := d.mc.Get(c)
  25. defer conn.Close()
  26. if err = conn.Set(&memcache.Item{
  27. Key: "ping",
  28. Value: []byte{1},
  29. Expiration: 86400,
  30. }); err != nil {
  31. log.Error("conn.Set(ping, 1) error(%v)", err)
  32. }
  33. return
  34. }
  35. // -------- base --------- //
  36. // BaseInfoCache get base info from mc.
  37. func (d *Dao) BaseInfoCache(c context.Context, mid int64) (info *model.BaseInfo, err error) {
  38. key := fmt.Sprintf(model.CacheKeyBase, mid)
  39. conn := d.mc.Get(c)
  40. defer conn.Close()
  41. item, err := conn.Get(key)
  42. if err != nil {
  43. if err == memcache.ErrNotFound {
  44. err = nil
  45. return
  46. }
  47. log.Error("conn.Get(%s) error(%v)", key, err)
  48. return
  49. }
  50. info = &model.BaseInfo{}
  51. if err = conn.Scan(item, info); err != nil {
  52. log.Error("conn.Scan(%s) error(%v)", string(item.Value), err)
  53. }
  54. return
  55. }
  56. // BatchBaseInfoCache get batch base info from mc.
  57. func (d *Dao) BatchBaseInfoCache(c context.Context, mids []int64) (cached map[int64]*model.BaseInfo, missed []int64, err error) {
  58. cached = make(map[int64]*model.BaseInfo, len(mids))
  59. if len(mids) == 0 {
  60. return
  61. }
  62. keys := make([]string, 0, len(mids))
  63. midmap := make(map[string]int64, len(mids))
  64. for _, mid := range mids {
  65. k := fmt.Sprintf(model.CacheKeyBase, mid)
  66. keys = append(keys, k)
  67. midmap[k] = mid
  68. }
  69. conn := d.mc.Get(c)
  70. defer conn.Close()
  71. bases, err := conn.GetMulti(keys)
  72. if err != nil {
  73. log.Error("conn.Gets(%v) error(%v)", keys, err)
  74. return
  75. }
  76. for _, base := range bases {
  77. b := &model.BaseInfo{}
  78. if err = conn.Scan(base, b); err != nil {
  79. log.Error("json.Unmarshal(%v) error(%v)", base.Value, err)
  80. return
  81. }
  82. cached[midmap[base.Key]] = b
  83. delete(midmap, base.Key)
  84. }
  85. missed = make([]int64, 0, len(midmap))
  86. for _, bid := range midmap {
  87. missed = append(missed, bid)
  88. }
  89. return
  90. }
  91. // SetBatchBaseInfoCache set batch base info to mc.
  92. func (d *Dao) SetBatchBaseInfoCache(c context.Context, bs []*model.BaseInfo) (err error) {
  93. for _, info := range bs {
  94. d.SetBaseInfoCache(c, info.Mid, info)
  95. }
  96. return
  97. }
  98. // SetBaseInfoCache set base info to mc
  99. func (d *Dao) SetBaseInfoCache(c context.Context, mid int64, info *model.BaseInfo) (err error) {
  100. key := fmt.Sprintf(model.CacheKeyBase, mid)
  101. conn := d.mc.Get(c)
  102. defer conn.Close()
  103. if err = conn.Set(&memcache.Item{
  104. Key: key,
  105. Object: info,
  106. Flags: memcache.FlagProtobuf,
  107. Expiration: d.baseTTL,
  108. }); err != nil {
  109. log.Error("conn.Set(%s, %v) error(%v)", key, info, err)
  110. }
  111. return
  112. }
  113. // DelBaseInfoCache delete baseInfo cache.
  114. func (d *Dao) DelBaseInfoCache(c context.Context, mid int64) (err error) {
  115. key := fmt.Sprintf(model.CacheKeyBase, mid)
  116. conn := d.mc.Get(c)
  117. defer conn.Close()
  118. if err = conn.Delete(key); err != nil {
  119. if err == memcache.ErrNotFound {
  120. err = nil
  121. return
  122. }
  123. log.Error("conn.Delete(%s) error(%v)", key, err)
  124. }
  125. return
  126. }
  127. // -------- base --------- //
  128. // ----- exp ------ //
  129. // Exp get user exp from cache,if miss get from db.
  130. func (d *Dao) expCache(c context.Context, mid int64) (exp int64, err error) {
  131. key := expKey(mid)
  132. conn := d.mc.Get(c)
  133. res, err := conn.Get(key)
  134. defer conn.Close()
  135. if err != nil {
  136. return
  137. }
  138. exp, _ = strconv.ParseInt(string(res.Value), 10, 64)
  139. return
  140. }
  141. // ExpsCache get users exp cache.
  142. func (d *Dao) expsCache(c context.Context, mids []int64) (exps map[int64]int64, miss []int64, err error) {
  143. var keys []string
  144. for _, mid := range mids {
  145. keys = append(keys, expKey(mid))
  146. }
  147. conn := d.mc.Get(c)
  148. defer conn.Close()
  149. its, err := conn.GetMulti(keys)
  150. if err != nil {
  151. return
  152. }
  153. exps = make(map[int64]int64)
  154. for _, mid := range mids {
  155. if it, ok := its[expKey(mid)]; ok {
  156. exp, _ := strconv.ParseInt(string(it.Value), 10, 64)
  157. exps[mid] = exp
  158. } else {
  159. miss = append(miss, mid)
  160. }
  161. }
  162. return
  163. }
  164. // SetExpCache set user exp cache.
  165. func (d *Dao) SetExpCache(c context.Context, mid, exp int64) (err error) {
  166. conn := d.mc.Get(c)
  167. defer conn.Close()
  168. if err = conn.Set(&memcache.Item{
  169. Key: expKey(mid),
  170. Value: []byte(strconv.FormatInt(exp, 10)),
  171. Expiration: _expExpire,
  172. }); err != nil {
  173. err = errors.WithStack(err)
  174. return
  175. }
  176. return
  177. }
  178. // moralCache get moral from cache.
  179. func (d *Dao) moralCache(c context.Context, mid int64) (moral *model.Moral, err error) {
  180. key := moralKey(mid)
  181. conn := d.mc.Get(c)
  182. item, err := conn.Get(key)
  183. defer conn.Close()
  184. if err != nil {
  185. return
  186. }
  187. moral = &model.Moral{}
  188. if err = conn.Scan(item, moral); err != nil {
  189. log.Error("conn.Scan(%s) error(%v)", string(item.Value), err)
  190. }
  191. return
  192. }
  193. // SetMoralCache set moral to mc
  194. func (d *Dao) SetMoralCache(c context.Context, mid int64, moral *model.Moral) (err error) {
  195. key := moralKey(mid)
  196. conn := d.mc.Get(c)
  197. defer conn.Close()
  198. if conn.Set(&memcache.Item{
  199. Key: key,
  200. Object: moral,
  201. Flags: memcache.FlagProtobuf,
  202. Expiration: d.moralTTL,
  203. }); err != nil {
  204. log.Error("conn.Set(%s, %v) error(%v)", key, moral, err)
  205. }
  206. return
  207. }
  208. // DelMoralCache delete moral cache.
  209. func (d *Dao) DelMoralCache(c context.Context, mid int64) (err error) {
  210. key := moralKey(mid)
  211. conn := d.mc.Get(c)
  212. defer conn.Close()
  213. if err = conn.Delete(key); err != nil {
  214. if err == memcache.ErrNotFound {
  215. err = nil
  216. return
  217. }
  218. log.Error("DelMoralCache conn.Delete(%s) error(%v)", key, err)
  219. }
  220. return
  221. }
  222. // ------realname------
  223. func realnameInfoKey(mid int64) string {
  224. return fmt.Sprintf("realname_info_%d", mid)
  225. }
  226. func realnameCaptureTimesKey(mid int64) string {
  227. return fmt.Sprintf("realname_cap_times_%d", mid)
  228. }
  229. func realnameCaptureCodeKey(mid int64) string {
  230. return fmt.Sprintf("realname_cap_code_%d", mid)
  231. }
  232. func realnameCaptureErrTimesKey(mid int64) string {
  233. return fmt.Sprintf("realname_cap_err_times%d", mid)
  234. }
  235. // RealnameCaptureTimesCache is
  236. func (d *Dao) RealnameCaptureTimesCache(c context.Context, mid int64) (times int, err error) {
  237. var (
  238. key = realnameCaptureTimesKey(mid)
  239. conn = d.mc.Get(c)
  240. item *memcache.Item
  241. )
  242. defer conn.Close()
  243. if item, err = conn.Get(key); err != nil {
  244. if err == memcache.ErrNotFound {
  245. err = nil
  246. times = -1
  247. return
  248. }
  249. err = errors.Wrapf(err, "conn.Get(%s)", key)
  250. return
  251. }
  252. if err = conn.Scan(item, &times); err != nil {
  253. err = errors.Wrapf(err, "conn.Scan(%+v)", item)
  254. return
  255. }
  256. return
  257. }
  258. // IncreaseRealnameCaptureTimes is
  259. func (d *Dao) IncreaseRealnameCaptureTimes(c context.Context, mid int64) (err error) {
  260. var (
  261. key = realnameCaptureTimesKey(mid)
  262. conn = d.mc.Get(c)
  263. )
  264. defer conn.Close()
  265. if _, err = conn.Increment(key, 1); err != nil {
  266. err = errors.Wrapf(err, "conn.Increment(%s,1)", key)
  267. return
  268. }
  269. return
  270. }
  271. // SetRealnameCaptureTimes is
  272. func (d *Dao) SetRealnameCaptureTimes(c context.Context, mid int64, times int) (err error) {
  273. var (
  274. key = realnameCaptureTimesKey(mid)
  275. conn = d.mc.Get(c)
  276. )
  277. defer conn.Close()
  278. if err = conn.Set(&memcache.Item{Key: key, Object: times, Flags: memcache.FlagJSON, Expiration: d.captureTimesTTL}); err != nil {
  279. err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, times)
  280. return
  281. }
  282. return
  283. }
  284. // RealnameCaptureCodeCache .
  285. // return code : -1 , if code not found
  286. // RealnameCaptureCodeCache is
  287. func (d *Dao) RealnameCaptureCodeCache(c context.Context, mid int64) (code int, err error) {
  288. var (
  289. key = realnameCaptureCodeKey(mid)
  290. conn = d.mc.Get(c)
  291. item *memcache.Item
  292. )
  293. defer conn.Close()
  294. if item, err = conn.Get(key); err != nil {
  295. if err == memcache.ErrNotFound {
  296. err = nil
  297. code = -1
  298. return
  299. }
  300. err = errors.Wrapf(err, "conn.Get(%s)", key)
  301. return
  302. }
  303. if err = conn.Scan(item, &code); err != nil {
  304. err = errors.Wrapf(err, "conn.Scan(%+v)", item)
  305. return
  306. }
  307. return
  308. }
  309. // RealnameInfoCache is.
  310. func (d *Dao) RealnameInfoCache(c context.Context, mid int64) (info *model.RealnameCacheInfo, err error) {
  311. var (
  312. key = realnameInfoKey(mid)
  313. conn = d.mc.Get(c)
  314. item *memcache.Item
  315. )
  316. defer conn.Close()
  317. if item, err = conn.Get(key); err != nil {
  318. if err == memcache.ErrNotFound {
  319. err = nil
  320. info = nil
  321. return
  322. }
  323. err = errors.Wrapf(err, "conn.Get(%s)", key)
  324. return
  325. }
  326. info = &model.RealnameCacheInfo{}
  327. if err = conn.Scan(item, &info); err != nil {
  328. err = errors.Wrapf(err, "conn.Scan(%+v)", item)
  329. return
  330. }
  331. return
  332. }
  333. // SetRealnameInfo is.
  334. func (d *Dao) SetRealnameInfo(c context.Context, mid int64, info *model.RealnameCacheInfo) (err error) {
  335. var (
  336. key = realnameInfoKey(mid)
  337. conn = d.mc.Get(c)
  338. )
  339. defer conn.Close()
  340. if err = conn.Set(&memcache.Item{Key: key, Object: info, Flags: memcache.FlagJSON, Expiration: d.applyInfoTTL}); err != nil {
  341. err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, info)
  342. return
  343. }
  344. return
  345. }
  346. // SetRealnameCaptureCode is
  347. func (d *Dao) SetRealnameCaptureCode(c context.Context, mid int64, code int) (err error) {
  348. var (
  349. key = realnameCaptureCodeKey(mid)
  350. conn = d.mc.Get(c)
  351. )
  352. defer conn.Close()
  353. if err = conn.Set(&memcache.Item{Key: key, Object: code, Flags: memcache.FlagJSON, Expiration: d.captureCodeTTL}); err != nil {
  354. err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, code)
  355. return
  356. }
  357. return
  358. }
  359. // DeleteRealnameCaptureCode is
  360. func (d *Dao) DeleteRealnameCaptureCode(c context.Context, mid int64) (err error) {
  361. var (
  362. key = realnameCaptureCodeKey(mid)
  363. conn = d.mc.Get(c)
  364. )
  365. defer conn.Close()
  366. if err = conn.Delete(key); err != nil {
  367. if err == memcache.ErrNotFound {
  368. err = nil
  369. return
  370. }
  371. err = errors.Wrapf(err, "conn.Delete(%s)", key)
  372. return
  373. }
  374. return
  375. }
  376. // DeleteRealnameInfo is
  377. func (d *Dao) DeleteRealnameInfo(c context.Context, mid int64) (err error) {
  378. var (
  379. key = realnameInfoKey(mid)
  380. conn = d.mc.Get(c)
  381. )
  382. defer conn.Close()
  383. if err = conn.Delete(key); err != nil {
  384. if err == memcache.ErrNotFound {
  385. err = nil
  386. return
  387. }
  388. err = errors.Wrapf(err, "conn.Delete(%s)", key)
  389. return
  390. }
  391. return
  392. }
  393. // RealnameCaptureErrTimesCache is
  394. func (d *Dao) RealnameCaptureErrTimesCache(c context.Context, mid int64) (times int, err error) {
  395. var (
  396. key = realnameCaptureErrTimesKey(mid)
  397. conn = d.mc.Get(c)
  398. item *memcache.Item
  399. )
  400. defer conn.Close()
  401. if item, err = conn.Get(key); err != nil {
  402. if err == memcache.ErrNotFound {
  403. err = nil
  404. times = -1
  405. return
  406. }
  407. err = errors.Wrapf(err, "conn.Get(%s)", key)
  408. return
  409. }
  410. if err = conn.Scan(item, &times); err != nil {
  411. err = errors.Wrapf(err, "conn.Scan(%+v)", item)
  412. return
  413. }
  414. return
  415. }
  416. // SetRealnameCaptureErrTimes is
  417. func (d *Dao) SetRealnameCaptureErrTimes(c context.Context, mid int64, times int) (err error) {
  418. var (
  419. key = realnameCaptureErrTimesKey(mid)
  420. conn = d.mc.Get(c)
  421. )
  422. defer conn.Close()
  423. if err = conn.Set(&memcache.Item{Key: key, Object: times, Flags: memcache.FlagJSON, Expiration: d.captureErrTimesTTL}); err != nil {
  424. err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, times)
  425. return
  426. }
  427. return
  428. }
  429. // IncreaseRealnameCaptureErrTimes is
  430. func (d *Dao) IncreaseRealnameCaptureErrTimes(c context.Context, mid int64) (err error) {
  431. var (
  432. key = realnameCaptureErrTimesKey(mid)
  433. conn = d.mc.Get(c)
  434. )
  435. defer conn.Close()
  436. if _, err = conn.Increment(key, 1); err != nil {
  437. err = errors.Wrapf(err, "conn.Increment(%s,1)", key)
  438. return
  439. }
  440. return
  441. }
  442. // DeleteRealnameCaptureErrTimes is
  443. func (d *Dao) DeleteRealnameCaptureErrTimes(c context.Context, mid int64) (err error) {
  444. var (
  445. key = realnameCaptureErrTimesKey(mid)
  446. conn = d.mc.Get(c)
  447. )
  448. defer conn.Close()
  449. if err = conn.Delete(key); err != nil {
  450. if err == memcache.ErrNotFound {
  451. err = nil
  452. err = nil
  453. return
  454. }
  455. err = errors.Wrapf(err, "conn.Delete(%s)", key)
  456. return
  457. }
  458. return
  459. }