123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- package dao
- import (
- "context"
- "fmt"
- "strconv"
- "go-common/app/service/main/relation/model"
- gmc "go-common/library/cache/memcache"
- "go-common/library/log"
- )
- const (
- _prefixFollowing = "pb_a_" // key of following
- _prefixFollower = "pb_f_" // key of follower
- _prefixTagCount = "rs_tmtc_%d" // key of relation tag by mid & tag's count
- _prefixTags = "tags_" // user tag info.
- _prefixGlobalHotRec = "gh_rec" // global hot rec
- _prefixStat = "c_" // key of stat
- _prefixFollowerNotify = "f_notify_"
- _emptyExpire = 20 * 24 * 3600
- _recExpire = 5 * 24 * 3600
- )
- func statKey(mid int64) string {
- return _prefixStat + strconv.FormatInt(mid, 10)
- }
- func tagsKey(mid int64) string {
- return _prefixTags + strconv.FormatInt(mid, 10)
- }
- func followingKey(mid int64) string {
- return _prefixFollowing + strconv.FormatInt(mid, 10)
- }
- func followerKey(mid int64) string {
- return _prefixFollower + strconv.FormatInt(mid, 10)
- }
- func tagCountKey(mid int64) string {
- return fmt.Sprintf(_prefixTagCount, mid)
- }
- func globalHotKey() string {
- return _prefixGlobalHotRec
- }
- func followerNotifySetting(mid int64) string {
- return _prefixFollowerNotify + strconv.FormatInt(mid, 10)
- }
- // pingMC ping memcache.
- func (d *Dao) pingMC(c context.Context) (err error) {
- conn := d.mc.Get(c)
- if err = conn.Set(&gmc.Item{Key: "ping", Value: []byte{1}, Expiration: d.mcExpire}); err != nil {
- log.Error("conn.Store(set, ping, 1) error(%v)", err)
- }
- conn.Close()
- return
- }
- // SetFollowingCache set following cache.
- func (d *Dao) SetFollowingCache(c context.Context, mid int64, followings []*model.Following) (err error) {
- return d.setFollowingCache(c, followingKey(mid), followings)
- }
- // FollowingCache get following cache.
- func (d *Dao) FollowingCache(c context.Context, mid int64) (followings []*model.Following, err error) {
- return d.followingCache(c, followingKey(mid))
- }
- // DelFollowingCache delete following cache.
- func (d *Dao) DelFollowingCache(c context.Context, mid int64) (err error) {
- return d.delFollowingCache(c, followingKey(mid))
- }
- // SetFollowerCache set follower cache.
- func (d *Dao) SetFollowerCache(c context.Context, mid int64, followers []*model.Following) (err error) {
- return d.setFollowingCache(c, followerKey(mid), followers)
- }
- // FollowerCache get follower cache.
- func (d *Dao) FollowerCache(c context.Context, mid int64) (followers []*model.Following, err error) {
- return d.followingCache(c, followerKey(mid))
- }
- // DelFollowerCache delete follower cache.
- func (d *Dao) DelFollowerCache(c context.Context, mid int64) (err error) {
- return d.delFollowingCache(c, followerKey(mid))
- }
- // setFollowingCache set following cache.
- func (d *Dao) setFollowingCache(c context.Context, key string, followings []*model.Following) (err error) {
- expire := d.followerExpire
- if len(followings) == 0 {
- expire = _emptyExpire
- }
- item := &gmc.Item{Key: key, Object: &model.FollowingList{FollowingList: followings}, Expiration: expire, Flags: gmc.FlagProtobuf}
- conn := d.mc.Get(c)
- if err = conn.Set(item); err != nil {
- log.Error("setFollowingCache err(%v)", err)
- }
- conn.Close()
- return
- }
- // followingCache get following cache.
- func (d *Dao) followingCache(c context.Context, key string) (followings []*model.Following, err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- item, err := conn.Get(key)
- if err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- return
- }
- log.Error("d.followingCache err(%v)", err)
- return
- }
- followingList := &model.FollowingList{}
- if err = conn.Scan(item, followingList); err != nil {
- log.Error("d.followinfCache err(%v)", err)
- }
- followings = followingList.FollowingList
- if followings == nil {
- followings = []*model.Following{}
- }
- return
- }
- // delFollowingCache delete following cache.
- func (d *Dao) delFollowingCache(c context.Context, key string) (err error) {
- conn := d.mc.Get(c)
- if err = conn.Delete(key); err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- } else {
- log.Error("conn.Delete(%s) error(%v)", key, err)
- }
- }
- conn.Close()
- return
- }
- // TagCountCache tag count cache
- func (d *Dao) TagCountCache(c context.Context, mid int64) (tagCount []*model.TagCount, err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- res, err := conn.Get(tagCountKey(mid))
- if err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- return
- }
- log.Error("mc.Get error(%v)", err)
- return
- }
- tc := &model.TagCountList{}
- if err = conn.Scan(res, tc); err != nil {
- log.Error("conn.Scan error(%v)", err)
- }
- tagCount = tc.TagCountList
- return
- }
- // SetTagCountCache set tag count cache
- func (d *Dao) SetTagCountCache(c context.Context, mid int64, tagCount []*model.TagCount) (err error) {
- item := &gmc.Item{Key: tagCountKey(mid), Object: &model.TagCountList{TagCountList: tagCount}, Expiration: d.mcExpire, Flags: gmc.FlagProtobuf}
- conn := d.mc.Get(c)
- if err = conn.Set(item); err != nil {
- log.Error("setTagMidFidCache(%s) error(%v)", tagCountKey(mid), err)
- }
- conn.Close()
- return
- }
- // DelTagCountCache del tag count cache
- func (d *Dao) DelTagCountCache(c context.Context, mid int64) (err error) {
- conn := d.mc.Get(c)
- if err = conn.Delete(tagCountKey(mid)); err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- } else {
- log.Error("conn.Delete(%s) error(%v)", tagCountKey(mid), err)
- }
- }
- conn.Close()
- return
- }
- // SetTagsCache set user tags cache.
- func (d *Dao) SetTagsCache(c context.Context, mid int64, tags *model.Tags) (err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- item := &gmc.Item{Key: tagsKey(mid), Object: tags, Expiration: d.mcExpire, Flags: gmc.FlagProtobuf}
- if err = conn.Set(item); err != nil {
- log.Error("SetTagsCache err %v", err)
- }
- return
- }
- // TagsCache get user tags.
- func (d *Dao) TagsCache(c context.Context, mid int64) (tags map[int64]*model.Tag, err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- res, err := conn.Get(tagsKey(mid))
- if err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- return
- }
- return
- }
- tag := new(model.Tags)
- if err = conn.Scan(res, tag); err != nil {
- return
- }
- tags = tag.Tags
- return
- }
- // DelTagsCache del user tags cache.
- func (d *Dao) DelTagsCache(c context.Context, mid int64) (err error) {
- conn := d.mc.Get(c)
- if err = conn.Delete(tagsKey(mid)); err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- } else {
- log.Error("conn.Delete(%s) error(%v)", tagCountKey(mid), err)
- }
- }
- conn.Close()
- return
- }
- // SetGlobalHotRecCache set global hot recommend cache.
- func (d *Dao) SetGlobalHotRecCache(c context.Context, fids []int64) (err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- item := &gmc.Item{Key: globalHotKey(), Object: &model.GlobalRec{Fids: fids}, Expiration: _recExpire, Flags: gmc.FlagProtobuf}
- if err = conn.Set(item); err != nil {
- log.Error("SetGlobalHotRecCache err %v", err)
- }
- return
- }
- // GlobalHotRecCache get global hot recommend.
- func (d *Dao) GlobalHotRecCache(c context.Context) (fs []int64, err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- res, err := conn.Get(globalHotKey())
- if err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- }
- return
- }
- gh := new(model.GlobalRec)
- if err = conn.Scan(res, gh); err != nil {
- return
- }
- fs = gh.Fids
- return
- }
- // SetStatCache set stat cache.
- func (d *Dao) SetStatCache(c context.Context, mid int64, st *model.Stat) error {
- conn := d.mc.Get(c)
- defer conn.Close()
- item := &gmc.Item{
- Key: statKey(mid),
- Object: st,
- Expiration: d.mcExpire,
- Flags: gmc.FlagProtobuf,
- }
- if err := conn.Set(item); err != nil {
- log.Error("Failed to set stat cache: mid: %d stat: %+v: %+v", mid, st, err)
- return err
- }
- return nil
- }
- // statCache get stat cache.
- func (d *Dao) statCache(c context.Context, mid int64) (*model.Stat, error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- item, err := conn.Get(statKey(mid))
- if err != nil {
- if err == gmc.ErrNotFound {
- return nil, nil
- }
- return nil, err
- }
- stat := &model.Stat{}
- if err := conn.Scan(item, stat); err != nil {
- log.Error("Failed to get stat cache: mid: %d: %+v", mid, err)
- return nil, err
- }
- return stat, nil
- }
- // statsCache get multi stat cache.
- func (d *Dao) statsCache(c context.Context, mids []int64) (map[int64]*model.Stat, []int64, error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- keys := make([]string, 0, len(mids))
- for _, mid := range mids {
- keys = append(keys, statKey(mid))
- }
- items, err := conn.GetMulti(keys)
- if err != nil {
- log.Error("Failed to get multi stat: keys: %+v: %+v", keys, err)
- return nil, nil, err
- }
- stats := make(map[int64]*model.Stat, len(mids))
- for _, item := range items {
- stat := &model.Stat{}
- if err := conn.Scan(item, stat); err != nil {
- log.Error("Failed to scan item: key: %s item: %+v: %+v", item.Key, item, err)
- continue
- }
- stats[stat.Mid] = stat
- }
- missed := make([]int64, 0, len(mids))
- for _, mid := range mids {
- if _, ok := stats[mid]; !ok {
- missed = append(missed, mid)
- }
- }
- return stats, missed, nil
- }
- // DelStatCache delete stat cache.
- func (d *Dao) DelStatCache(c context.Context, mid int64) error {
- conn := d.mc.Get(c)
- defer conn.Close()
- if err := conn.Delete(statKey(mid)); err != nil {
- if err == gmc.ErrNotFound {
- return nil
- }
- log.Error("Failed to delete stat cache: mid: %d: %+v", mid, err)
- return err
- }
- return nil
- }
- // GetFollowerNotifyCache get data from mc
- func (d *Dao) GetFollowerNotifyCache(c context.Context, mid int64) (res *model.FollowerNotifySetting, err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- key := followerNotifySetting(mid)
- reply, err := conn.Get(key)
- if err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- return
- }
- log.Errorv(c, log.KV("GetFollowerNotifyCache", fmt.Sprintf("%+v", err)), log.KV("key", key))
- return
- }
- res = &model.FollowerNotifySetting{}
- err = conn.Scan(reply, res)
- if err != nil {
- log.Errorv(c, log.KV("GetFollowerNotifyCache", fmt.Sprintf("%+v", err)), log.KV("key", key))
- return
- }
- return
- }
- // SetFollowerNotifyCache Set data to mc
- func (d *Dao) SetFollowerNotifyCache(c context.Context, mid int64, val *model.FollowerNotifySetting) (err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- key := followerNotifySetting(mid)
- item := &gmc.Item{
- Key: key,
- Object: val,
- Expiration: 86400,
- Flags: gmc.FlagJSON,
- }
- if err = conn.Set(item); err != nil {
- log.Errorv(c, log.KV("SetFollowerNotifyCache", fmt.Sprintf("%+v", err)), log.KV("key", key))
- return
- }
- return
- }
- // DelFollowerNotifyCache Del data from mc
- func (d *Dao) DelFollowerNotifyCache(c context.Context, mid int64) (err error) {
- conn := d.mc.Get(c)
- defer conn.Close()
- key := followerNotifySetting(mid)
- if err = conn.Delete(key); err != nil {
- if err == gmc.ErrNotFound {
- err = nil
- return
- }
- log.Errorv(c, log.KV("DelFollowerNotifyCache", fmt.Sprintf("%+v", err)), log.KV("key", key))
- return
- }
- return
- }
|