From 6e2da4f2f101aba773b63bfcdb3e55e6f1b39bac Mon Sep 17 00:00:00 2001 From: xban Date: Mon, 11 Mar 2024 15:37:25 +0800 Subject: [PATCH 1/7] refactor: relationDomain service On the basis of retaining the original code, the implementation of the interface has been replaced, generally completing the architectural direction of the OOP refactoring. --- .../relationDomain/handler/handler.go | 101 +++++ .../relationDomain/handler/handler_test.go | 1 + .../relationDomain/handler/typedef.go | 17 +- applications/relationDomain/main.go | 8 +- .../relationDomain/service/relation_count.go | 1 + .../relationDomain/service/service.go | 360 ++++++++++++++++++ .../relationDomain/service/typedef.go | 24 ++ 7 files changed, 510 insertions(+), 2 deletions(-) create mode 100644 applications/relationDomain/handler/handler.go create mode 100644 applications/relationDomain/handler/handler_test.go create mode 100644 applications/relationDomain/service/service.go create mode 100644 applications/relationDomain/service/typedef.go diff --git a/applications/relationDomain/handler/handler.go b/applications/relationDomain/handler/handler.go new file mode 100644 index 00000000..bdd6201f --- /dev/null +++ b/applications/relationDomain/handler/handler.go @@ -0,0 +1,101 @@ +package handler + +import ( + "context" + "github.com/TremblingV5/DouTok/applications/relationDomain/pack" + "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" + "github.com/TremblingV5/DouTok/pkg/errno" +) + +func (h *RelationDomainHandler) AddRelation(ctx context.Context, req *relationDomain.DoutokAddRelationRequest) (resp *relationDomain.DoutokAddRelationResponse, err error) { + resp = new(relationDomain.DoutokAddRelationResponse) + + err = h.service.AddRelation(ctx, req.UserId, req.ToUserId) + if err != nil { + pack.BuildRelationActionResp(err, resp) + return resp, nil + } + pack.BuildRelationActionResp(errno.Success, resp) + return resp, nil +} + +func (h *RelationDomainHandler) RmRelation(ctx context.Context, req *relationDomain.DoutokRmRelationRequest) (resp *relationDomain.DoutokRmRelationResponse, err error) { + resp = new(relationDomain.DoutokRmRelationResponse) + + err = h.service.RmRelation(ctx, req.UserId, req.ToUserId) + if err != nil { + pack.BuildRmRelationActionResp(err, resp) + return resp, nil + } + pack.BuildRmRelationActionResp(errno.Success, resp) + return resp, nil +} + +func (h *RelationDomainHandler) ListRelation(ctx context.Context, req *relationDomain.DoutokListRelationRequest) (resp *relationDomain.DoutokListRelationResponse, err error) { + + resp = new(relationDomain.DoutokListRelationResponse) + if req.ActionType == 0 { + // 关注 + followList, err := h.service.ListFollowList(ctx, req.UserId) + if err != nil { + pack.BuildRelationFollowListResp(err, resp) + return resp, nil + } + resp.UserList = followList + pack.BuildRelationFollowListResp(errno.Success, resp) + return resp, nil + } else if req.ActionType == 1 { + // 粉丝 + // 关注 + followerList, err := h.service.ListFollowerList(ctx, req.UserId) + if err != nil { + pack.BuildRelationFollowListResp(err, resp) + return resp, nil + } + resp.UserList = followerList + pack.BuildRelationFollowListResp(errno.Success, resp) + return resp, nil + } else if req.ActionType == 2 { + // 互相关注 + // 关注 + friendList, err := h.service.ListFriendList(ctx, req.UserId) + if err != nil { + pack.BuildRelationFollowListResp(err, resp) + return resp, nil + } + resp.UserList = friendList + pack.BuildRelationFollowListResp(errno.Success, resp) + return resp, nil + } + return resp, nil +} + +func (h *RelationDomainHandler) CountRelation(ctx context.Context, req *relationDomain.DoutokCountRelationRequest) (resp *relationDomain.DoutokCountRelationResponse, err error) { + resp = &relationDomain.DoutokCountRelationResponse{ + Result: make(map[int64]int64), + } + + /* + 0 -> 关注数 1 -> 粉丝数 + */ + if req.ActionType == 0 { + for _, v := range req.UserId { + follow, err := h.service.GetFollowCount(ctx, v) + if err != nil { + continue + } + resp.Result[v] = follow + } + } else if req.ActionType == 1 { + for _, v := range req.UserId { + follower, err := h.service.GetFollowerCount(ctx, v) + if err != nil { + continue + } + resp.Result[v] = follower + } + } + + pack.BuildRelationCountResp(errno.Success, resp) + return resp, nil +} diff --git a/applications/relationDomain/handler/handler_test.go b/applications/relationDomain/handler/handler_test.go new file mode 100644 index 00000000..abeebd16 --- /dev/null +++ b/applications/relationDomain/handler/handler_test.go @@ -0,0 +1 @@ +package handler diff --git a/applications/relationDomain/handler/typedef.go b/applications/relationDomain/handler/typedef.go index a136bca4..42781c86 100644 --- a/applications/relationDomain/handler/typedef.go +++ b/applications/relationDomain/handler/typedef.go @@ -1,3 +1,18 @@ package handler -type RelationDomainServiceImpl struct{} +import ( + "github.com/TremblingV5/DouTok/applications/relationDomain/service" +) + +type RelationDomainServiceImpl struct { +} + +type RelationDomainHandler struct { + service *service.RelationDomainService +} + +func NewRelationDomainHandler(service *service.RelationDomainService) *RelationDomainHandler { + return &RelationDomainHandler{ + service: service, + } +} diff --git a/applications/relationDomain/main.go b/applications/relationDomain/main.go index 76e8b895..5bebebbd 100644 --- a/applications/relationDomain/main.go +++ b/applications/relationDomain/main.go @@ -17,13 +17,19 @@ func init() { service.Init() } +func loadFeature() *handler.RelationDomainHandler { + // TODO xban 加载 repo 等其他对象 + relationService := service.NewRelationDomainService() + return handler.NewRelationDomainHandler(relationService) +} + func main() { options, shutdown := services.InitRPCServerArgs(constants.RELATION_DOMAIN_SERVER_NAME, service.DomainConfig.BaseConfig) defer shutdown() svr := relationdomainservice.NewServer( - new(handler.RelationDomainServiceImpl), + loadFeature(), options..., ) diff --git a/applications/relationDomain/service/relation_count.go b/applications/relationDomain/service/relation_count.go index 2ffe3b66..50d7a371 100644 --- a/applications/relationDomain/service/relation_count.go +++ b/applications/relationDomain/service/relation_count.go @@ -62,6 +62,7 @@ func (s *RelationCountService) GetFollowerCount(userId int64) (int64, error) { return follower, nil } +// hot todo: xban RelationCountService 这个方法是否可以移除了? func (s *RelationCountService) RelationCount(userId int64) (error, int64, int64) { // 读 cache 获取关注数 diff --git a/applications/relationDomain/service/service.go b/applications/relationDomain/service/service.go new file mode 100644 index 00000000..7af3a505 --- /dev/null +++ b/applications/relationDomain/service/service.go @@ -0,0 +1,360 @@ +package service + +import ( + "context" + "encoding/json" + "fmt" + "github.com/Shopify/sarama" + "github.com/TremblingV5/DouTok/kitex_gen/entity" + "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" + "github.com/TremblingV5/DouTok/pkg/constants" + "github.com/cloudwego/kitex/pkg/klog" +) + +func (s *RelationDomainService) AddRelation(ctx context.Context, userId, toUserId int64) error { + + err, followList := ReadFollowListFromCache(fmt.Sprint(userId)) + if err != nil { + return err + } + + isFollowed := false + + for _, v := range followList { + if v == toUserId { + isFollowed = true + break + } + } + + if !isFollowed { + isFollowed, err = ReadIsFollowFromDB(userId, toUserId) + if err != nil { + isFollowed = false + } + } + + if isFollowed { + return nil + } + + // 在 SafeMap 中更新局部关注数和粉丝数 + followKey := fmt.Sprintf("%s%d", constants.FollowCount, userId) + followerKey := fmt.Sprintf("%s%d", constants.FollowerCount, toUserId) + follow, ok := ConcurrentMap.Get(followKey) + if !ok { + klog.Infof("get follow count from concurrentMap false") + } + follower, ok := ConcurrentMap.Get(followerKey) + if !ok { + klog.Infof("get follow count from concurrentMap false") + } + op := int64(1) + // TODO 如果关注或者取关对应的增加 safemap 值,前提是需要验证重复性操作 + mu.Lock() + if follow == nil { + klog.Infof("set follow %s, %d\n", followKey, op) + ConcurrentMap.Set(followKey, op) + } else { + klog.Infof("set follow %s, %d\n", followKey, follow.(int64)+op) + ConcurrentMap.Set(followKey, follow.(int64)+op) + } + if follower == nil { + klog.Infof("set follower %s, %d\n", followerKey, op) + ConcurrentMap.Set(followerKey, op) + } else { + klog.Infof("set follower %s, %d\n", followerKey, follower.(int64)+op) + ConcurrentMap.Set(followerKey, follower.(int64)+op) + } + follow, ok = ConcurrentMap.Get(followKey) + if !ok { + klog.Errorf("concurrentMap get false") + } + follower, ok = ConcurrentMap.Get(followerKey) + if !ok { + klog.Errorf("concurrentMap get false") + } + klog.Infof("%s follow = %d\n", followKey, follow.(int64)) + klog.Infof("%s follower = %d\n", followerKey, follower.(int64)) + mu.Unlock() + // 使用同步producer,将消息存入 kafka + // 构建消息 + val, err := json.Marshal(NewRelation(userId, toUserId, 0)) + if err != nil { + return err + } + msg := &sarama.ProducerMessage{ + Topic: ViperConfig.Viper.GetStringSlice("Kafka.Topics")[0], + Value: sarama.StringEncoder(val), + } + partition, offset, err := SyncProducer.SendMessage(msg) + + if err == nil { + klog.Infof("produce success, partition: %d, offset: %d\n", partition, offset) + } else { + return err + } + + return nil +} + +func (s *RelationDomainService) RmRelation(ctx context.Context, userId, toUserId int64) error { + // 从 SafeMap 中更新局部关注数和粉丝数 + followKey := fmt.Sprintf("%s%d", constants.FollowCount, userId) + followerKey := fmt.Sprintf("%s%d", constants.FollowerCount, toUserId) + follow, ok := ConcurrentMap.Get(followKey) + if !ok { + klog.Infof("get follow count from concurrentMap false") + } + follower, ok := ConcurrentMap.Get(followerKey) + if !ok { + klog.Infof("get follow count from concurrentMap false") + } + op := int64(-1) + // TODO 如果关注或者取关对应的增加 safemap 值,前提是需要验证重复性操作 + mu.Lock() + if follow == nil { + klog.Infof("set follow %s, %d\n", followKey, op) + ConcurrentMap.Set(followKey, op) + } else { + klog.Infof("set follow %s, %d\n", followKey, follow.(int64)+op) + ConcurrentMap.Set(followKey, follow.(int64)+op) + } + if follower == nil { + klog.Infof("set follower %s, %d\n", followerKey, op) + ConcurrentMap.Set(followerKey, op) + } else { + klog.Infof("set follower %s, %d\n", followerKey, follow.(int64)+op) + ConcurrentMap.Set(followerKey, follower.(int64)+op) + } + follow, ok = ConcurrentMap.Get(followKey) + if !ok { + klog.Errorf("concurrentMap get false") + } + follower, ok = ConcurrentMap.Get(followerKey) + if !ok { + klog.Errorf("concurrentMap get false") + } + klog.Infof("%s follow = %d\n", followKey, follow.(int64)) + klog.Infof("%s follower = %d\n", followerKey, follower.(int64)) + mu.Unlock() + // 使用同步producer,将消息存入 kafka + // 构建消息 + val, err := json.Marshal(NewRelation(userId, toUserId, 1)) + if err != nil { + return err + } + msg := &sarama.ProducerMessage{ + Topic: ViperConfig.Viper.GetStringSlice("Kafka.Topics")[0], + Value: sarama.StringEncoder(val), + } + partition, offset, err := SyncProducer.SendMessage(msg) + + if err == nil { + klog.Infof("produce success, partition: %d, offset: %d\n", partition, offset) + } else { + return err + } + + return nil +} + +func (s *RelationDomainService) ListFollowList(ctx context.Context, userId int64) ([]*entity.User, error) { + // 从 cache 读 + err, follow := ReadFollowListFromCache(fmt.Sprintf("%d", userId)) + if err != nil || follow == nil { + klog.Errorf("read follow list from cache error, err = %s", err) + // 从 db 读 + err, relationList := ReadFollowListFromDB(userId) + if err != nil { + klog.Errorf("read follow list from db error, err = %s", err) + return nil, err + } else { + // 添加 cache + err := WriteFollowListToCache(fmt.Sprintf("%d", userId), relationList) + if err != nil { + klog.Errorf("update follow list to cache error, err = %s", err) + } + // 为 follow 赋值 + list := make([]int64, len(relationList)) + for _, v := range relationList { + list = append(list, v.ToUserId) + } + follow = list + } + } + + // 去用户服务查询 follow list 的 user 信息 + // request := new(userDomain.DoutokGetUserInfoRequest) + // request.UserId = follow + // resp, err := rpc.UserDomainRPCClient.GetUserInfo(context.Background(), request) + // if err != nil { + // return nil, err + // } + + // var result []*entity.User + // for _, v := range resp.UserList { + // result = append(result, v) + // } + result := make([]*entity.User, 1) + for _, v := range follow { + result = append(result, &entity.User{ + Id: v, + }) + } + + return result, nil +} + +func (s *RelationDomainService) ListFollowerList(ctx context.Context, userId int64) ([]*entity.User, error) { + // 从 cache 读 + err, follower := ReadFollowerListFromCache(fmt.Sprintf("%d", userId)) + if err != nil || follower == nil { + klog.Errorf("read follower list from cache error, err = %s", err) + // 从 db 读 + err, relationList := ReadFollowerListFromDB(userId) + if err != nil { + klog.Errorf("read follower list from db error, err = %s", err) + return nil, err + } else { + // 添加 cache + err := WriteFollowerListToCache(fmt.Sprintf("%d", userId), relationList) + if err != nil { + klog.Errorf("update follower list to cache error, err = %s", err) + } + // 为 follower 赋值 + list := make([]int64, len(relationList)) + for _, v := range relationList { + list = append(list, v.UserId) + } + follower = list + } + } + // 去用户服务查询 follow list 的 user 信息 + // request := new(userDomain.DoutokGetUserInfoRequest) + // request.UserId = follower + // resp, err := rpc.UserDomainRPCClient.GetUserInfo(context.Background(), request) + // if err != nil { + // return nil, err + // } + + // var result []*entity.User + // for _, v := range resp.UserList { + // result = append(result, v) + // } + + result := make([]*entity.User, 0) + for _, v := range follower { + result = append(result, &entity.User{ + Id: v, + }) + } + + return result, nil +} + +func (s *RelationDomainService) ListFriendList(ctx context.Context, userId int64) ([]*entity.User, error) { + // 从 cache 读 + err, friendList := GetFriendList(userId) + if err != nil { + return nil, err + } + // 去用户服务查询 friendList 的 user 信息 + // reqUser := new(userDomain.DoutokGetUserInfoRequest) + // reqUser.UserId = friendList + // respUser, err := rpc.UserDomainRPCClient.GetUserInfo(context.Background(), reqUser) + // if err != nil { + // return nil, err + // } + // 去 message 服务查询对应好友列表的最新消息 返回一个 map + reqMsg := new(relationDomain.DoutokListRelationRequest) + reqMsg.UserId = userId + reqMsg.ActionType = 2 + // reqMsg.FriendIdList = friendList + // _, err = rpc.RelationDomainRPCClient.ListRelation(context.Background(), reqMsg) + + // for k, v := range respMsg.UserList { + // klog.Infof("res key = %d, msg = %s\n", k, v.Content) + // } + + if err != nil { + return nil, err + } + var fList []*entity.User + for _, v := range friendList { + // 0为当前请求用户接受的消息,1为当前请求用户发送的消息 + // msgType := 0 + // if respMsg.UserList[v.Id].FromUserId == userId { + // msgType = 1 + // } + + // klog.Infof("user_id = %s, msgType = %d\n", respMsg.UserList[v.Id].Content, int64(msgType)) + + //friend := &entity.FriendUser{ + // User: &entity.User{ + // Id: v.Id, + // Name: v.Name, + // FollowCount: v.FollowCount, + // FollowerCount: v.FollowerCount, + // IsFollow: v.IsFollow, + // Avatar: v.Avatar, + // }, + // Message: respMsg.Result[v.Id].Content, + // MsgType: int64(msgType), + //} + friend := &entity.User{ + Id: v, + } + fList = append(fList, friend) + } + return fList, nil +} + +func (s *RelationDomainService) GetFollowCount(ctx context.Context, userId int64) (int64, error) { + err, follow := ReadFollowCountFromCache(fmt.Sprintf("%d", userId)) + if err != nil || follow == 0 { + // 记录日志 + klog.Errorf("read follow count from cache error, err = %s", err) + // 读 db 获取关注数 + err, follow = ReadFollowCountFromDB(userId) + if err != nil { + // 记录日志 + klog.Errorf("read follow count from db error, err = %s", err) + follow = 0 + } + // 新增 cache 关注数 + err = WriteFollowCountToCache(fmt.Sprintf("%d", userId), follow) + if err != nil { + // 记录日志 + klog.Errorf("update follow count to cache error, err = %s", err) + } + } + return follow, nil +} + +func (s *RelationDomainService) GetFollowerCount(ctx context.Context, userId int64) (int64, error) { + err, follower := ReadFollowerCountFromCache(fmt.Sprintf("%d", userId)) + if err != nil || follower == 0 { + // 记录日志 + klog.Errorf("read follower count from cache error, err = %s", err) + // 读 db 获取粉丝数 + err, follower = ReadFollowerCountFromDB(userId) + if err != nil { + // 记录日志 + klog.Errorf("read follower count from db error, err = %s", err) + follower = 0 + } + // 新增 cache 粉丝数 + err = WriteFollowerCountToCache(fmt.Sprintf("%d", userId), follower) + if err != nil { + // 记录日志 + klog.Errorf("update follower count to cache error, err = %s", err) + } + } + return follower, nil +} + +func (s *RelationDomainService) GetFriendCount(ctx context.Context, userId int64) (int64, error) { + //TODO implement me + panic("implement me") +} diff --git a/applications/relationDomain/service/typedef.go b/applications/relationDomain/service/typedef.go new file mode 100644 index 00000000..5cc3bba1 --- /dev/null +++ b/applications/relationDomain/service/typedef.go @@ -0,0 +1,24 @@ +package service + +import ( + "context" + entity "github.com/TremblingV5/DouTok/kitex_gen/entity" +) + +type RelationDomainService struct { +} + +func NewRelationDomainService() *RelationDomainService { + return &RelationDomainService{} +} + +type IService interface { + AddRelation(ctx context.Context, userId, toUserId int64) error + RmRelation(ctx context.Context, userId, toUserId int64) error + ListFollowList(ctx context.Context, userId int64) ([]*entity.User, error) + ListFollowerList(ctx context.Context, userId int64) ([]*entity.User, error) + ListFriendList(ctx context.Context, userId int64) ([]*entity.User, error) + GetFollowCount(ctx context.Context, userId int64) (int64, error) + GetFollowerCount(ctx context.Context, userId int64) (int64, error) + GetFriendCount(ctx context.Context, userId int64) (int64, error) +} From 9e936e6572de628caab12f398b1a04203bf7c956 Mon Sep 17 00:00:00 2001 From: xban Date: Mon, 11 Mar 2024 16:59:25 +0800 Subject: [PATCH 2/7] test: add simple ut --- .../relationDomain/handler/handler_test.go | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/applications/relationDomain/handler/handler_test.go b/applications/relationDomain/handler/handler_test.go index abeebd16..43d47441 100644 --- a/applications/relationDomain/handler/handler_test.go +++ b/applications/relationDomain/handler/handler_test.go @@ -1 +1,64 @@ package handler + +import ( + "context" + "github.com/TremblingV5/DouTok/applications/relationDomain/service" + "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" + "github.com/TremblingV5/DouTok/pkg/errno" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" +) + +func NewTestHandler() *RelationDomainHandler { + service.Init() + return NewRelationDomainHandler(service.NewRelationDomainService()) +} + +func TestRelationDomainHandler_ListRelation(t *testing.T) { + ctx := context.Background() + handler := NewTestHandler() + + t.Run("ListFollowList", func(t *testing.T) { + req := &relationDomain.DoutokListRelationRequest{ + ActionType: 0, + UserId: rand.Int63(), + } + + resp, err := handler.ListRelation(ctx, req) + + assert.NoError(t, err) + assert.NotNil(t, resp) + // assert.Equal(t, followList, resp.UserList) + assert.Equal(t, errno.SuccessCode, resp.StatusCode) + }) + + t.Run("ListFollowerList", func(t *testing.T) { + req := &relationDomain.DoutokListRelationRequest{ + ActionType: 1, + UserId: rand.Int63(), + } + + resp, err := handler.ListRelation(ctx, req) + + assert.NoError(t, err) + assert.NotNil(t, resp) + //assert.Equal(t, followerList, resp.UserList) + assert.Equal(t, errno.SuccessCode, resp.StatusCode) + }) + + t.Run("ListFriendList", func(t *testing.T) { + req := &relationDomain.DoutokListRelationRequest{ + ActionType: 2, + UserId: rand.Int63(), + } + + resp, err := handler.ListRelation(ctx, req) + + assert.NoError(t, err) + assert.NotNil(t, resp) + //assert.Equal(t, friendList, resp.UserList) + assert.Equal(t, errno.SuccessCode, resp.StatusCode) + }) +} From bf3743e97ab9f26b8550e8cf96e15844d43d9f8c Mon Sep 17 00:00:00 2001 From: xban Date: Wed, 13 Mar 2024 11:26:46 +0800 Subject: [PATCH 3/7] style: rename for cleaner --- applications/relationDomain/handler/handler.go | 8 ++++---- .../relationDomain/handler/handler_test.go | 4 ++-- applications/relationDomain/handler/typedef.go | 8 ++++---- applications/relationDomain/main.go | 6 +++--- applications/relationDomain/service/service.go | 16 ++++++++-------- applications/relationDomain/service/typedef.go | 6 +++--- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/applications/relationDomain/handler/handler.go b/applications/relationDomain/handler/handler.go index bdd6201f..2a110911 100644 --- a/applications/relationDomain/handler/handler.go +++ b/applications/relationDomain/handler/handler.go @@ -7,7 +7,7 @@ import ( "github.com/TremblingV5/DouTok/pkg/errno" ) -func (h *RelationDomainHandler) AddRelation(ctx context.Context, req *relationDomain.DoutokAddRelationRequest) (resp *relationDomain.DoutokAddRelationResponse, err error) { +func (h *Handler) AddRelation(ctx context.Context, req *relationDomain.DoutokAddRelationRequest) (resp *relationDomain.DoutokAddRelationResponse, err error) { resp = new(relationDomain.DoutokAddRelationResponse) err = h.service.AddRelation(ctx, req.UserId, req.ToUserId) @@ -19,7 +19,7 @@ func (h *RelationDomainHandler) AddRelation(ctx context.Context, req *relationDo return resp, nil } -func (h *RelationDomainHandler) RmRelation(ctx context.Context, req *relationDomain.DoutokRmRelationRequest) (resp *relationDomain.DoutokRmRelationResponse, err error) { +func (h *Handler) RmRelation(ctx context.Context, req *relationDomain.DoutokRmRelationRequest) (resp *relationDomain.DoutokRmRelationResponse, err error) { resp = new(relationDomain.DoutokRmRelationResponse) err = h.service.RmRelation(ctx, req.UserId, req.ToUserId) @@ -31,7 +31,7 @@ func (h *RelationDomainHandler) RmRelation(ctx context.Context, req *relationDom return resp, nil } -func (h *RelationDomainHandler) ListRelation(ctx context.Context, req *relationDomain.DoutokListRelationRequest) (resp *relationDomain.DoutokListRelationResponse, err error) { +func (h *Handler) ListRelation(ctx context.Context, req *relationDomain.DoutokListRelationRequest) (resp *relationDomain.DoutokListRelationResponse, err error) { resp = new(relationDomain.DoutokListRelationResponse) if req.ActionType == 0 { @@ -70,7 +70,7 @@ func (h *RelationDomainHandler) ListRelation(ctx context.Context, req *relationD return resp, nil } -func (h *RelationDomainHandler) CountRelation(ctx context.Context, req *relationDomain.DoutokCountRelationRequest) (resp *relationDomain.DoutokCountRelationResponse, err error) { +func (h *Handler) CountRelation(ctx context.Context, req *relationDomain.DoutokCountRelationRequest) (resp *relationDomain.DoutokCountRelationResponse, err error) { resp = &relationDomain.DoutokCountRelationResponse{ Result: make(map[int64]int64), } diff --git a/applications/relationDomain/handler/handler_test.go b/applications/relationDomain/handler/handler_test.go index 43d47441..07ffdca0 100644 --- a/applications/relationDomain/handler/handler_test.go +++ b/applications/relationDomain/handler/handler_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/assert" ) -func NewTestHandler() *RelationDomainHandler { +func NewTestHandler() *Handler { service.Init() - return NewRelationDomainHandler(service.NewRelationDomainService()) + return New(service.New()) } func TestRelationDomainHandler_ListRelation(t *testing.T) { diff --git a/applications/relationDomain/handler/typedef.go b/applications/relationDomain/handler/typedef.go index 42781c86..47f08568 100644 --- a/applications/relationDomain/handler/typedef.go +++ b/applications/relationDomain/handler/typedef.go @@ -7,12 +7,12 @@ import ( type RelationDomainServiceImpl struct { } -type RelationDomainHandler struct { - service *service.RelationDomainService +type Handler struct { + service *service.Service } -func NewRelationDomainHandler(service *service.RelationDomainService) *RelationDomainHandler { - return &RelationDomainHandler{ +func New(service *service.Service) *Handler { + return &Handler{ service: service, } } diff --git a/applications/relationDomain/main.go b/applications/relationDomain/main.go index 5bebebbd..db285a1d 100644 --- a/applications/relationDomain/main.go +++ b/applications/relationDomain/main.go @@ -17,10 +17,10 @@ func init() { service.Init() } -func loadFeature() *handler.RelationDomainHandler { +func loadFeature() *handler.Handler { // TODO xban 加载 repo 等其他对象 - relationService := service.NewRelationDomainService() - return handler.NewRelationDomainHandler(relationService) + relationService := service.New() + return handler.New(relationService) } func main() { diff --git a/applications/relationDomain/service/service.go b/applications/relationDomain/service/service.go index 7af3a505..768d58f9 100644 --- a/applications/relationDomain/service/service.go +++ b/applications/relationDomain/service/service.go @@ -11,7 +11,7 @@ import ( "github.com/cloudwego/kitex/pkg/klog" ) -func (s *RelationDomainService) AddRelation(ctx context.Context, userId, toUserId int64) error { +func (s *Service) AddRelation(ctx context.Context, userId, toUserId int64) error { err, followList := ReadFollowListFromCache(fmt.Sprint(userId)) if err != nil { @@ -98,7 +98,7 @@ func (s *RelationDomainService) AddRelation(ctx context.Context, userId, toUserI return nil } -func (s *RelationDomainService) RmRelation(ctx context.Context, userId, toUserId int64) error { +func (s *Service) RmRelation(ctx context.Context, userId, toUserId int64) error { // 从 SafeMap 中更新局部关注数和粉丝数 followKey := fmt.Sprintf("%s%d", constants.FollowCount, userId) followerKey := fmt.Sprintf("%s%d", constants.FollowerCount, toUserId) @@ -159,7 +159,7 @@ func (s *RelationDomainService) RmRelation(ctx context.Context, userId, toUserId return nil } -func (s *RelationDomainService) ListFollowList(ctx context.Context, userId int64) ([]*entity.User, error) { +func (s *Service) ListFollowList(ctx context.Context, userId int64) ([]*entity.User, error) { // 从 cache 读 err, follow := ReadFollowListFromCache(fmt.Sprintf("%d", userId)) if err != nil || follow == nil { @@ -206,7 +206,7 @@ func (s *RelationDomainService) ListFollowList(ctx context.Context, userId int64 return result, nil } -func (s *RelationDomainService) ListFollowerList(ctx context.Context, userId int64) ([]*entity.User, error) { +func (s *Service) ListFollowerList(ctx context.Context, userId int64) ([]*entity.User, error) { // 从 cache 读 err, follower := ReadFollowerListFromCache(fmt.Sprintf("%d", userId)) if err != nil || follower == nil { @@ -253,7 +253,7 @@ func (s *RelationDomainService) ListFollowerList(ctx context.Context, userId int return result, nil } -func (s *RelationDomainService) ListFriendList(ctx context.Context, userId int64) ([]*entity.User, error) { +func (s *Service) ListFriendList(ctx context.Context, userId int64) ([]*entity.User, error) { // 从 cache 读 err, friendList := GetFriendList(userId) if err != nil { @@ -310,7 +310,7 @@ func (s *RelationDomainService) ListFriendList(ctx context.Context, userId int64 return fList, nil } -func (s *RelationDomainService) GetFollowCount(ctx context.Context, userId int64) (int64, error) { +func (s *Service) GetFollowCount(ctx context.Context, userId int64) (int64, error) { err, follow := ReadFollowCountFromCache(fmt.Sprintf("%d", userId)) if err != nil || follow == 0 { // 记录日志 @@ -332,7 +332,7 @@ func (s *RelationDomainService) GetFollowCount(ctx context.Context, userId int64 return follow, nil } -func (s *RelationDomainService) GetFollowerCount(ctx context.Context, userId int64) (int64, error) { +func (s *Service) GetFollowerCount(ctx context.Context, userId int64) (int64, error) { err, follower := ReadFollowerCountFromCache(fmt.Sprintf("%d", userId)) if err != nil || follower == 0 { // 记录日志 @@ -354,7 +354,7 @@ func (s *RelationDomainService) GetFollowerCount(ctx context.Context, userId int return follower, nil } -func (s *RelationDomainService) GetFriendCount(ctx context.Context, userId int64) (int64, error) { +func (s *Service) GetFriendCount(ctx context.Context, userId int64) (int64, error) { //TODO implement me panic("implement me") } diff --git a/applications/relationDomain/service/typedef.go b/applications/relationDomain/service/typedef.go index 5cc3bba1..6ca9c32d 100644 --- a/applications/relationDomain/service/typedef.go +++ b/applications/relationDomain/service/typedef.go @@ -5,11 +5,11 @@ import ( entity "github.com/TremblingV5/DouTok/kitex_gen/entity" ) -type RelationDomainService struct { +type Service struct { } -func NewRelationDomainService() *RelationDomainService { - return &RelationDomainService{} +func New() *Service { + return &Service{} } type IService interface { From eea135cf9385e16087cb1cb25274d0d7a7a81795 Mon Sep 17 00:00:00 2001 From: xban Date: Wed, 13 Mar 2024 17:41:46 +0800 Subject: [PATCH 4/7] refactor: remove RelationDomainServiceImpl --- .../relationDomain/handler/add_relation.go | 21 --------- .../relationDomain/handler/count_relation.go | 39 --------------- .../relationDomain/handler/list_relation.go | 47 ------------------- .../relationDomain/handler/rm_relation.go | 21 --------- .../relationDomain/handler/typedef.go | 3 -- 5 files changed, 131 deletions(-) delete mode 100644 applications/relationDomain/handler/add_relation.go delete mode 100644 applications/relationDomain/handler/count_relation.go delete mode 100644 applications/relationDomain/handler/list_relation.go delete mode 100644 applications/relationDomain/handler/rm_relation.go diff --git a/applications/relationDomain/handler/add_relation.go b/applications/relationDomain/handler/add_relation.go deleted file mode 100644 index c6953aaa..00000000 --- a/applications/relationDomain/handler/add_relation.go +++ /dev/null @@ -1,21 +0,0 @@ -package handler - -import ( - "context" - "github.com/TremblingV5/DouTok/applications/relationDomain/pack" - "github.com/TremblingV5/DouTok/applications/relationDomain/service" - "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" - "github.com/TremblingV5/DouTok/pkg/errno" -) - -func (s *RelationDomainServiceImpl) AddRelation(ctx context.Context, req *relationDomain.DoutokAddRelationRequest) (resp *relationDomain.DoutokAddRelationResponse, err error) { - resp = new(relationDomain.DoutokAddRelationResponse) - - err = service.NewRelationActionService(ctx).AddRelation(req) - if err != nil { - pack.BuildRelationActionResp(err, resp) - return resp, nil - } - pack.BuildRelationActionResp(errno.Success, resp) - return resp, nil -} diff --git a/applications/relationDomain/handler/count_relation.go b/applications/relationDomain/handler/count_relation.go deleted file mode 100644 index 3e3a9e5a..00000000 --- a/applications/relationDomain/handler/count_relation.go +++ /dev/null @@ -1,39 +0,0 @@ -package handler - -import ( - "context" - "github.com/TremblingV5/DouTok/applications/relationDomain/pack" - "github.com/TremblingV5/DouTok/applications/relationDomain/service" - "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" - "github.com/TremblingV5/DouTok/pkg/errno" -) - -func (s *RelationDomainServiceImpl) CountRelation(ctx context.Context, req *relationDomain.DoutokCountRelationRequest) (resp *relationDomain.DoutokCountRelationResponse, err error) { - resp = &relationDomain.DoutokCountRelationResponse{ - Result: make(map[int64]int64), - } - - /* - 0 -> 关注数 1 -> 粉丝数 - */ - if req.ActionType == 0 { - for _, v := range req.UserId { - follow, err := service.NewRelationCountService(ctx).GetFollowCount(v) - if err != nil { - continue - } - resp.Result[v] = follow - } - } else if req.ActionType == 1 { - for _, v := range req.UserId { - follower, err := service.NewRelationCountService(ctx).GetFollowerCount(v) - if err != nil { - continue - } - resp.Result[v] = follower - } - } - - pack.BuildRelationCountResp(errno.Success, resp) - return resp, nil -} diff --git a/applications/relationDomain/handler/list_relation.go b/applications/relationDomain/handler/list_relation.go deleted file mode 100644 index bafd0e8d..00000000 --- a/applications/relationDomain/handler/list_relation.go +++ /dev/null @@ -1,47 +0,0 @@ -package handler - -import ( - "context" - "github.com/TremblingV5/DouTok/applications/relationDomain/pack" - "github.com/TremblingV5/DouTok/applications/relationDomain/service" - "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" - "github.com/TremblingV5/DouTok/pkg/errno" -) - -func (s *RelationDomainServiceImpl) ListRelation(ctx context.Context, req *relationDomain.DoutokListRelationRequest) (resp *relationDomain.DoutokListRelationResponse, err error) { - resp = new(relationDomain.DoutokListRelationResponse) - if req.ActionType == 0 { - // 关注 - err, followList := service.NewRelationFollowListService(ctx).RelationFollowList(req) - if err != nil { - pack.BuildRelationFollowListResp(err, resp) - return resp, nil - } - resp.UserList = followList - pack.BuildRelationFollowListResp(errno.Success, resp) - return resp, nil - } else if req.ActionType == 1 { - // 粉丝 - // 关注 - err, followerList := service.NewRelationFollowerListService(ctx).RelationFollowerList(req) - if err != nil { - pack.BuildRelationFollowListResp(err, resp) - return resp, nil - } - resp.UserList = followerList - pack.BuildRelationFollowListResp(errno.Success, resp) - return resp, nil - } else if req.ActionType == 2 { - // 互相关注 - // 关注 - err, friendList := service.NewRelationFriendListService(ctx).RelationFriendList(req) - if err != nil { - pack.BuildRelationFollowListResp(err, resp) - return resp, nil - } - resp.UserList = friendList - pack.BuildRelationFollowListResp(errno.Success, resp) - return resp, nil - } - return resp, nil -} diff --git a/applications/relationDomain/handler/rm_relation.go b/applications/relationDomain/handler/rm_relation.go deleted file mode 100644 index afc0ce67..00000000 --- a/applications/relationDomain/handler/rm_relation.go +++ /dev/null @@ -1,21 +0,0 @@ -package handler - -import ( - "context" - "github.com/TremblingV5/DouTok/applications/relationDomain/pack" - "github.com/TremblingV5/DouTok/applications/relationDomain/service" - "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" - "github.com/TremblingV5/DouTok/pkg/errno" -) - -func (s *RelationDomainServiceImpl) RmRelation(ctx context.Context, req *relationDomain.DoutokRmRelationRequest) (resp *relationDomain.DoutokRmRelationResponse, err error) { - resp = new(relationDomain.DoutokRmRelationResponse) - - err = service.NewRelationActionService(ctx).RmRelation(req) - if err != nil { - pack.BuildRmRelationActionResp(err, resp) - return resp, nil - } - pack.BuildRmRelationActionResp(errno.Success, resp) - return resp, nil -} diff --git a/applications/relationDomain/handler/typedef.go b/applications/relationDomain/handler/typedef.go index 47f08568..ecea5667 100644 --- a/applications/relationDomain/handler/typedef.go +++ b/applications/relationDomain/handler/typedef.go @@ -4,9 +4,6 @@ import ( "github.com/TremblingV5/DouTok/applications/relationDomain/service" ) -type RelationDomainServiceImpl struct { -} - type Handler struct { service *service.Service } From a803798f19368ca760f0074adef9d4a104fd3e3c Mon Sep 17 00:00:00 2001 From: xban Date: Wed, 27 Mar 2024 15:18:37 +0800 Subject: [PATCH 5/7] =?UTF-8?q?refactor:=20=E4=B8=BB=E8=A6=81=E6=98=AF=20r?= =?UTF-8?q?edis=20=E9=83=A8=E5=88=86=20oop=20=E7=9A=84=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dal/repository/relation/repository.go | 78 +++++++ applications/relationDomain/main.go | 12 +- .../redis/followCountRedis/redis.go | 47 +++++ .../redis/followListRedis/redis.go | 60 ++++++ .../redis/followerCountRedis/redis.go | 47 +++++ .../redis/followerListRedis/redis.go | 56 +++++ applications/relationDomain/service/init.go | 10 - .../relationDomain/service/relation_action.go | 191 ------------------ .../relationDomain/service/relation_count.go | 143 ------------- .../service/relation_follow_list.go | 58 ------ .../service/relation_follower_list.go | 59 ------ .../relationDomain/service/service.go | 16 +- .../relationDomain/service/typedef.go | 62 +++++- pkg/redisHandle/set.go | 4 + 14 files changed, 370 insertions(+), 473 deletions(-) create mode 100644 applications/relationDomain/dal/repository/relation/repository.go create mode 100644 applications/relationDomain/redis/followCountRedis/redis.go create mode 100644 applications/relationDomain/redis/followListRedis/redis.go create mode 100644 applications/relationDomain/redis/followerCountRedis/redis.go create mode 100644 applications/relationDomain/redis/followerListRedis/redis.go diff --git a/applications/relationDomain/dal/repository/relation/repository.go b/applications/relationDomain/dal/repository/relation/repository.go new file mode 100644 index 00000000..0a9be1e3 --- /dev/null +++ b/applications/relationDomain/dal/repository/relation/repository.go @@ -0,0 +1,78 @@ +package relation + +import ( + "github.com/TremblingV5/DouTok/applications/relationDomain/dal/model" + "github.com/TremblingV5/DouTok/applications/relationDomain/dal/query" + "github.com/TremblingV5/DouTok/applications/relationDomain/pack" + "github.com/TremblingV5/DouTok/pkg/utils" + "gorm.io/gorm" +) + +type Repository interface { + Save(relation *pack.Relation) error + SaveList(relationList []*pack.Relation) error + + //LoadOneByUserId(userId int64) (*pack.Relation, error) + //LoadOneByToUserId(toUserId int64) (*pack.Relation, error) + //LoadListByUserId(userId int64) ([]*pack.Relation, error) + //LoadListByToUserId(toUserId int64) ([]*pack.Relation, error) + //LoadCountByUserId(userId int64) (int64, error) + //LoadCountByToUserId(toUserId int64) (int64, error) +} + +type PersistRepository struct { + relation query.IRelationDo +} + +func New(db *gorm.DB) *PersistRepository { + return &PersistRepository{ + relation: query.Relation.WithContext(db.Statement.Context), + } +} + +func (p *PersistRepository) Save(rel *pack.Relation) error { + res, err := p.relation.Where( + query.Relation.UserId.Eq(rel.UserId), + query.Relation.ToUserId.Eq(rel.ToUserId), + ).Find() + if err != nil { + return err + } + if len(res) > 0 { + // 已经存在关注关系 + _, err := p.relation.Where( + query.Relation.UserId.Eq(rel.UserId), + query.Relation.ToUserId.Eq(rel.ToUserId), + ).Update( + query.Relation.Status, rel.ActionType, + ) + if err != nil { + return err + } + } else { + // 不存在则插入 + id := utils.GetSnowFlakeId().Int64() + err := p.relation.Create( + &model.Relation{ + ID: id, + UserId: rel.UserId, + ToUserId: rel.ToUserId, + Status: int(rel.ActionType), + }, + ) + if err != nil { + return err + } + } + return nil +} + +func (p *PersistRepository) SaveList(relations []*pack.Relation) error { + for _, rel := range relations { + err := p.Save(rel) + if err != nil { + return err + } + } + return nil +} diff --git a/applications/relationDomain/main.go b/applications/relationDomain/main.go index db285a1d..53e03fd3 100644 --- a/applications/relationDomain/main.go +++ b/applications/relationDomain/main.go @@ -1,6 +1,8 @@ package main import ( + "github.com/TremblingV5/DouTok/applications/relationDomain/dal/query" + relationRepo "github.com/TremblingV5/DouTok/applications/relationDomain/dal/repository/relation" "github.com/TremblingV5/DouTok/applications/relationDomain/handler" "github.com/TremblingV5/DouTok/applications/relationDomain/service" "github.com/TremblingV5/DouTok/kitex_gen/relationDomain/relationdomainservice" @@ -18,8 +20,14 @@ func init() { } func loadFeature() *handler.Handler { - // TODO xban 加载 repo 等其他对象 - relationService := service.New() + db, err := service.DomainConfig.MySQL.InitDB() + if err != nil { + panic(err) + } + query.SetDefault(db) + + repo := relationRepo.New(db) + relationService := service.New(repo) return handler.New(relationService) } diff --git a/applications/relationDomain/redis/followCountRedis/redis.go b/applications/relationDomain/redis/followCountRedis/redis.go new file mode 100644 index 00000000..d4fe4ed1 --- /dev/null +++ b/applications/relationDomain/redis/followCountRedis/redis.go @@ -0,0 +1,47 @@ +package followCountRedis + +import ( + "context" + "fmt" + "github.com/TremblingV5/DouTok/pkg/constants" + redishandle "github.com/TremblingV5/DouTok/pkg/redisHandle" + "strconv" +) + +type Client struct { + client *redishandle.RedisClient +} + +func NewClient(client *redishandle.RedisClient) *Client { + return &Client{ + client: client, + } +} + +func (c *Client) Get(ctx context.Context, userId int64) (int64, error) { + ret, err := c.client.HGet(ctx, fmt.Sprintf("%d", userId), constants.FollowCount) + if err != nil { + return 0, err + } + follow, err := strconv.ParseInt(ret, 10, 64) + if err != nil { + return 0, err + } + return follow, nil +} + +func (c *Client) Set(ctx context.Context, userId, count int64) error { + err := c.client.HSet(ctx, fmt.Sprintf("%d", userId), constants.FollowCount, fmt.Sprintf("%d", count)) + if err != nil { + return err + } + return nil +} + +func (c *Client) Del(ctx context.Context, userId int64) error { + _, err := c.client.HDel(ctx, fmt.Sprintf("%d", userId), constants.FollowCount) + if err != nil { + return err + } + return nil +} diff --git a/applications/relationDomain/redis/followListRedis/redis.go b/applications/relationDomain/redis/followListRedis/redis.go new file mode 100644 index 00000000..63c474b2 --- /dev/null +++ b/applications/relationDomain/redis/followListRedis/redis.go @@ -0,0 +1,60 @@ +package followListRedis + +import ( + "context" + "fmt" + "github.com/TremblingV5/DouTok/applications/relationDomain/dal/model" + "github.com/TremblingV5/DouTok/pkg/constants" + redishandle "github.com/TremblingV5/DouTok/pkg/redisHandle" + "github.com/go-redis/redis/v8" + "strconv" +) + +type Client struct { + client *redishandle.RedisClient +} + +func NewClient(client *redishandle.RedisClient) *Client { + return &Client{ + client: client, + } +} + +func getRedisKeyByUserId(userId int64) string { + return constants.FollowListPrefix + fmt.Sprintf("%d", userId) +} + +func (c *Client) Get(ctx context.Context, userId int64) ([]int64, error) { + key := getRedisKeyByUserId(userId) + res, err := c.client.HGetAll(ctx, key) + if err != nil { + return nil, err + } + ret := make([]int64, 0) + for k, v := range res { + kI64, _ := strconv.ParseInt(k, 10, 64) + if v == "1" { + ret = append(ret, kI64) + } + } + + if len(ret) <= 0 { + return ret, redis.Nil + } + return ret, nil +} + +func (c *Client) Set(ctx context.Context, userId int64, relations []*model.Relation) error { + val := make([]string, len(relations)*2) + for _, v := range relations { + val = append(val, fmt.Sprintf("%d", v.ToUserId)) + val = append(val, fmt.Sprintf("%d", v.Status)) + } + + key := getRedisKeyByUserId(userId) + err := c.client.HSetMore(ctx, key, val...) + if err != nil { + return err + } + return nil +} diff --git a/applications/relationDomain/redis/followerCountRedis/redis.go b/applications/relationDomain/redis/followerCountRedis/redis.go new file mode 100644 index 00000000..54ca03a9 --- /dev/null +++ b/applications/relationDomain/redis/followerCountRedis/redis.go @@ -0,0 +1,47 @@ +package followerCountRedis + +import ( + "context" + "fmt" + "github.com/TremblingV5/DouTok/pkg/constants" + redishandle "github.com/TremblingV5/DouTok/pkg/redisHandle" + "strconv" +) + +type Client struct { + client *redishandle.RedisClient +} + +func NewClient(client *redishandle.RedisClient) *Client { + return &Client{ + client: client, + } +} + +func (c *Client) Get(ctx context.Context, userId int64) (int64, error) { + ret, err := c.client.HGet(ctx, fmt.Sprintf("%d", userId), constants.FollowerCount) + if err != nil { + return 0, err + } + follow, err := strconv.ParseInt(ret, 10, 64) + if err != nil { + return 0, err + } + return follow, nil +} + +func (c *Client) Set(ctx context.Context, userId, count int64) error { + err := c.client.HSet(ctx, fmt.Sprintf("%d", userId), constants.FollowerCount, fmt.Sprintf("%d", count)) + if err != nil { + return err + } + return nil +} + +func (c *Client) Del(ctx context.Context, userId int64) error { + _, err := c.client.HDel(ctx, fmt.Sprintf("%d", userId), constants.FollowerCount) + if err != nil { + return err + } + return nil +} diff --git a/applications/relationDomain/redis/followerListRedis/redis.go b/applications/relationDomain/redis/followerListRedis/redis.go new file mode 100644 index 00000000..079f5447 --- /dev/null +++ b/applications/relationDomain/redis/followerListRedis/redis.go @@ -0,0 +1,56 @@ +package followerListRedis + +import ( + "context" + "fmt" + "github.com/TremblingV5/DouTok/applications/relationDomain/dal/model" + "github.com/TremblingV5/DouTok/pkg/constants" + redishandle "github.com/TremblingV5/DouTok/pkg/redisHandle" + "strconv" +) + +type Client struct { + client *redishandle.RedisClient +} + +func NewClient(client *redishandle.RedisClient) *Client { + return &Client{ + client: client, + } +} + +func getRedisKeyByUserId(userId int64) string { + return constants.FollowerListPrefix + fmt.Sprintf("%d", userId) +} + +func (c *Client) Set(ctx context.Context, userId int64, relations []*model.Relation) error { + val := make([]string, len(relations)*2) + for _, v := range relations { + val = append(val, fmt.Sprintf("%d", v.ToUserId)) + val = append(val, fmt.Sprintf("%d", v.Status)) + } + + key := getRedisKeyByUserId(userId) + err := c.client.HSetMore(ctx, key, val...) + if err != nil { + return err + } + return nil +} + +func (c *Client) Get(ctx context.Context, userId int64) ([]int64, error) { + key := getRedisKeyByUserId(userId) + res, err := c.client.HGetAll(ctx, key) + if err != nil { + return nil, err + } + ret := make([]int64, 0) + for k, v := range res { + kI64, _ := strconv.ParseInt(k, 10, 64) + if v == "1" { + ret = append(ret, kI64) + } + } + + return ret, nil +} diff --git a/applications/relationDomain/service/init.go b/applications/relationDomain/service/init.go index 0ccde669..43823fa1 100644 --- a/applications/relationDomain/service/init.go +++ b/applications/relationDomain/service/init.go @@ -8,7 +8,6 @@ import ( "sync" "github.com/Shopify/sarama" - "github.com/TremblingV5/DouTok/applications/relationDomain/dal/query" "github.com/TremblingV5/DouTok/pkg/dtviper" "github.com/TremblingV5/DouTok/pkg/kafka" "github.com/TremblingV5/DouTok/pkg/safeMap" @@ -38,7 +37,6 @@ func Init() { InitSyncProducer() InitConsumerGroup() InitId() - InitDB() InitSafeMap() InitMutex() @@ -76,14 +74,6 @@ func InitId() { utils.InitSnowFlake(node) } -func InitDB() { - db, err := DomainConfig.MySQL.InitDB() - if err != nil { - panic(err) - } - query.SetDefault(db) -} - func InitSafeMap() { ConcurrentMap = safeMap.New() } diff --git a/applications/relationDomain/service/relation_action.go b/applications/relationDomain/service/relation_action.go index c5d4447d..d67863aa 100644 --- a/applications/relationDomain/service/relation_action.go +++ b/applications/relationDomain/service/relation_action.go @@ -1,16 +1,5 @@ package service -import ( - "context" - "encoding/json" - "fmt" - - "github.com/Shopify/sarama" - "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" - "github.com/TremblingV5/DouTok/pkg/constants" - "github.com/cloudwego/kitex/pkg/klog" -) - type Relation struct { UserId int64 `json:"user_id"` ToUserId int64 `json:"to_user_id"` @@ -24,183 +13,3 @@ func NewRelation(userId int64, toUserId int64, actionType int64) *Relation { ActionType: int32(actionType), } } - -type RelationActionService struct { - ctx context.Context -} - -func NewRelationActionService(ctx context.Context) *RelationActionService { - return &RelationActionService{ctx: ctx} -} - -func (s *RelationActionService) AddRelation(req *relationDomain.DoutokAddRelationRequest) error { - err, followList := ReadFollowListFromCache(fmt.Sprint(req.UserId)) - if err != nil { - return err - } - - isFollowed := false - - for _, v := range followList { - if v == req.ToUserId { - isFollowed = true - break - } - } - - if !isFollowed { - isFollowed, err = ReadIsFollowFromDB(req.UserId, req.ToUserId) - if err != nil { - isFollowed = false - } - } - - if isFollowed { - return nil - } - - // 在 SafeMap 中更新局部关注数和粉丝数 - followKey := fmt.Sprintf("%s%d", constants.FollowCount, req.UserId) - followerKey := fmt.Sprintf("%s%d", constants.FollowerCount, req.ToUserId) - follow, ok := ConcurrentMap.Get(followKey) - if !ok { - klog.Infof("get follow count from concurrentMap false") - } - follower, ok := ConcurrentMap.Get(followerKey) - if !ok { - klog.Infof("get follow count from concurrentMap false") - } - op := int64(1) - // TODO 如果关注或者取关对应的增加 safemap 值,前提是需要验证重复性操作 - mu.Lock() - if follow == nil { - klog.Infof("set follow %s, %d\n", followKey, op) - ConcurrentMap.Set(followKey, op) - } else { - klog.Infof("set follow %s, %d\n", followKey, follow.(int64)+op) - ConcurrentMap.Set(followKey, follow.(int64)+op) - } - if follower == nil { - klog.Infof("set follower %s, %d\n", followerKey, op) - ConcurrentMap.Set(followerKey, op) - } else { - klog.Infof("set follower %s, %d\n", followerKey, follower.(int64)+op) - ConcurrentMap.Set(followerKey, follower.(int64)+op) - } - follow, ok = ConcurrentMap.Get(followKey) - if !ok { - klog.Errorf("concurrentMap get false") - } - follower, ok = ConcurrentMap.Get(followerKey) - if !ok { - klog.Errorf("concurrentMap get false") - } - klog.Infof("%s follow = %d\n", followKey, follow.(int64)) - klog.Infof("%s follower = %d\n", followerKey, follower.(int64)) - mu.Unlock() - // 使用同步producer,将消息存入 kafka - // 构建消息 - val, err := json.Marshal(NewRelation(req.UserId, req.ToUserId, 0)) - if err != nil { - return err - } - msg := &sarama.ProducerMessage{ - Topic: ViperConfig.Viper.GetStringSlice("Kafka.Topics")[0], - Value: sarama.StringEncoder(val), - } - partition, offset, err := SyncProducer.SendMessage(msg) - - if err == nil { - klog.Infof("produce success, partition: %d, offset: %d\n", partition, offset) - } else { - return err - } - - return nil -} - -func (s *RelationActionService) RmRelation(req *relationDomain.DoutokRmRelationRequest) error { - err, followList := ReadFollowListFromCache(fmt.Sprint(req.UserId)) - if err != nil { - return nil - } - - isFollowed := false - - for _, v := range followList { - if v == req.ToUserId { - isFollowed = true - break - } - } - - if !isFollowed { - isFollowed, err = ReadIsFollowFromDB(req.UserId, req.ToUserId) - if err != nil { - isFollowed = true - } - } - - if !isFollowed { - return nil - } - - // 在 SafeMap 中更新局部关注数和粉丝数 - followKey := fmt.Sprintf("%s%d", constants.FollowCount, req.UserId) - followerKey := fmt.Sprintf("%s%d", constants.FollowerCount, req.ToUserId) - follow, ok := ConcurrentMap.Get(followKey) - if !ok { - klog.Infof("get follow count from concurrentMap false") - } - follower, ok := ConcurrentMap.Get(followerKey) - if !ok { - klog.Infof("get follow count from concurrentMap false") - } - op := int64(-1) - // TODO 如果关注或者取关对应的增加 safemap 值,前提是需要验证重复性操作 - mu.Lock() - if follow == nil { - klog.Infof("set follow %s, %d\n", followKey, op) - ConcurrentMap.Set(followKey, op) - } else { - klog.Infof("set follow %s, %d\n", followKey, follow.(int64)+op) - ConcurrentMap.Set(followKey, follow.(int64)+op) - } - if follower == nil { - klog.Infof("set follower %s, %d\n", followerKey, op) - ConcurrentMap.Set(followerKey, op) - } else { - klog.Infof("set follower %s, %d\n", followerKey, follower.(int64)+op) - ConcurrentMap.Set(followerKey, follower.(int64)+op) - } - follow, ok = ConcurrentMap.Get(followKey) - if !ok { - klog.Errorf("concurrentMap get false") - } - follower, ok = ConcurrentMap.Get(followerKey) - if !ok { - klog.Errorf("concurrentMap get false") - } - klog.Infof("%s follow = %d\n", followKey, follow.(int64)) - klog.Infof("%s follower = %d\n", followerKey, follower.(int64)) - mu.Unlock() - // 使用同步producer,将消息存入 kafka - // 构建消息 - val, err := json.Marshal(NewRelation(req.UserId, req.ToUserId, 1)) - if err != nil { - return err - } - msg := &sarama.ProducerMessage{ - Topic: ViperConfig.Viper.GetStringSlice("Kafka.Topics")[0], - Value: sarama.StringEncoder(val), - } - partition, offset, err := SyncProducer.SendMessage(msg) - - if err == nil { - klog.Infof("produce success, partition: %d, offset: %d\n", partition, offset) - } else { - return err - } - - return nil -} diff --git a/applications/relationDomain/service/relation_count.go b/applications/relationDomain/service/relation_count.go index 50d7a371..263a72ed 100644 --- a/applications/relationDomain/service/relation_count.go +++ b/applications/relationDomain/service/relation_count.go @@ -2,110 +2,11 @@ package service import ( "context" - "fmt" - "github.com/TremblingV5/DouTok/applications/relationDomain/dal/model" "github.com/TremblingV5/DouTok/applications/relationDomain/dal/query" "github.com/TremblingV5/DouTok/pkg/constants" - "github.com/cloudwego/kitex/pkg/klog" ) -type RelationCountService struct { - ctx context.Context -} - -func NewRelationCountService(ctx context.Context) *RelationCountService { - return &RelationCountService{ctx: ctx} -} - -func (s *RelationCountService) GetFollowCount(userId int64) (int64, error) { - err, follow := ReadFollowCountFromCache(fmt.Sprintf("%d", userId)) - if err != nil || follow == 0 { - // 记录日志 - klog.Errorf("read follow count from cache error, err = %s", err) - // 读 db 获取关注数 - err, follow = ReadFollowCountFromDB(userId) - if err != nil { - // 记录日志 - klog.Errorf("read follow count from db error, err = %s", err) - follow = 0 - } - // 新增 cache 关注数 - err = WriteFollowCountToCache(fmt.Sprintf("%d", userId), follow) - if err != nil { - // 记录日志 - klog.Errorf("update follow count to cache error, err = %s", err) - } - } - return follow, nil -} - -func (s *RelationCountService) GetFollowerCount(userId int64) (int64, error) { - err, follower := ReadFollowerCountFromCache(fmt.Sprintf("%d", userId)) - if err != nil || follower == 0 { - // 记录日志 - klog.Errorf("read follower count from cache error, err = %s", err) - // 读 db 获取粉丝数 - err, follower = ReadFollowerCountFromDB(userId) - if err != nil { - // 记录日志 - klog.Errorf("read follower count from db error, err = %s", err) - follower = 0 - } - // 新增 cache 粉丝数 - err = WriteFollowerCountToCache(fmt.Sprintf("%d", userId), follower) - if err != nil { - // 记录日志 - klog.Errorf("update follower count to cache error, err = %s", err) - } - } - return follower, nil -} - -// hot todo: xban RelationCountService 这个方法是否可以移除了? -func (s *RelationCountService) RelationCount(userId int64) (error, int64, int64) { - - // 读 cache 获取关注数 - err, follow := ReadFollowCountFromCache(fmt.Sprintf("%d", userId)) - if err != nil || follow == 0 { - // 记录日志 - klog.Errorf("read follow count from cache error, err = %s", err) - // 读 db 获取关注数 - err, follow = ReadFollowCountFromDB(userId) - if err != nil { - // 记录日志 - klog.Errorf("read follow count from db error, err = %s", err) - follow = 0 - } - // 新增 cache 关注数 - err = WriteFollowCountToCache(fmt.Sprintf("%d", userId), follow) - if err != nil { - // 记录日志 - klog.Errorf("update follow count to cache error, err = %s", err) - } - } - // 读 cache 获取粉丝数 - err, follower := ReadFollowerCountFromCache(fmt.Sprintf("%d", userId)) - if err != nil || follower == 0 { - // 记录日志 - klog.Errorf("read follower count from cache error, err = %s", err) - // 读 db 获取粉丝数 - err, follower = ReadFollowerCountFromDB(userId) - if err != nil { - // 记录日志 - klog.Errorf("read follower count from db error, err = %s", err) - follower = 0 - } - // 新增 cache 粉丝数 - err = WriteFollowerCountToCache(fmt.Sprintf("%d", userId), follower) - if err != nil { - // 记录日志 - klog.Errorf("update follower count to cache error, err = %s", err) - } - } - return nil, follow, follower -} - func ReadFollowCountFromDB(user_id int64) (error, int64) { res, err := query.FollowCount.Where(query.FollowCount.UserId.Eq(user_id)).First() if err != nil { @@ -114,28 +15,6 @@ func ReadFollowCountFromDB(user_id int64) (error, int64) { return nil, res.Number } -func ReadFollowCountFromCache(user_id string) (error, int64) { - ret := RedisClient.HGet(context.Background(), user_id, constants.FollowCount) - err := ret.Err() - if err != nil { - return err, 0 - } - follow, err := ret.Int64() - if err != nil { - return err, 0 - } - return nil, follow -} - -func WriteFollowCountToCache(user_id string, follow int64) error { - ret := RedisClient.HSet(context.Background(), user_id, map[string]interface{}{constants.FollowCount: follow}) - err := ret.Err() - if err != nil { - return err - } - return nil -} - func UpdateFollowCountFromDB(user_id int64, op int64) error { res, err := query.FollowCount.Where( query.FollowCount.UserId.Eq(user_id), @@ -204,28 +83,6 @@ func ReadFollowerCountFromDB(user_id int64) (error, int64) { return nil, res.Number } -func ReadFollowerCountFromCache(user_id string) (error, int64) { - ret := RedisClient.HGet(context.Background(), user_id, constants.FollowerCount) - err := ret.Err() - if err != nil { - return err, 0 - } - follower, err := ret.Int64() - if err != nil { - return err, 0 - } - return nil, follower -} - -func WriteFollowerCountToCache(user_id string, follower int64) error { - ret := RedisClient.HSet(context.Background(), user_id, map[string]interface{}{constants.FollowerCount: follower}) - err := ret.Err() - if err != nil { - return err - } - return nil -} - func DeleteFollowerCountCache(user_id string) error { _, err := RedisClient.HDel(context.Background(), user_id, constants.FollowCount).Result() if err != nil { diff --git a/applications/relationDomain/service/relation_follow_list.go b/applications/relationDomain/service/relation_follow_list.go index 792c1423..72528a11 100644 --- a/applications/relationDomain/service/relation_follow_list.go +++ b/applications/relationDomain/service/relation_follow_list.go @@ -5,73 +5,15 @@ import ( "fmt" "strconv" - "github.com/cloudwego/kitex/pkg/klog" "github.com/go-redis/redis/v8" "github.com/TremblingV5/DouTok/applications/relationDomain/dal/model" "github.com/TremblingV5/DouTok/applications/relationDomain/dal/query" "github.com/TremblingV5/DouTok/applications/relationDomain/pack" - "github.com/TremblingV5/DouTok/kitex_gen/entity" - "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" "github.com/TremblingV5/DouTok/pkg/constants" "github.com/TremblingV5/DouTok/pkg/utils" ) -type RelationFollowListService struct { - ctx context.Context -} - -func NewRelationFollowListService(ctx context.Context) *RelationFollowListService { - return &RelationFollowListService{ctx: ctx} -} - -func (s *RelationFollowListService) RelationFollowList(req *relationDomain.DoutokListRelationRequest) (error, []*entity.User) { - // 从 cache 读 - err, follow := ReadFollowListFromCache(fmt.Sprintf("%d", req.UserId)) - if err != nil || follow == nil { - klog.Errorf("read follow list from cache error, err = %s", err) - // 从 db 读 - err, relationList := ReadFollowListFromDB(req.UserId) - if err != nil { - klog.Errorf("read follow list from db error, err = %s", err) - return err, nil - } else { - // 添加 cache - err := WriteFollowListToCache(fmt.Sprintf("%d", req.UserId), relationList) - if err != nil { - klog.Errorf("update follow list to cache error, err = %s", err) - } - // 为 follow 赋值 - list := make([]int64, len(relationList)) - for _, v := range relationList { - list = append(list, v.ToUserId) - } - follow = list - } - } - - // 去用户服务查询 follow list 的 user 信息 - // request := new(userDomain.DoutokGetUserInfoRequest) - // request.UserId = follow - // resp, err := rpc.UserDomainRPCClient.GetUserInfo(context.Background(), request) - // if err != nil { - // return err, nil - // } - - // var result []*entity.User - // for _, v := range resp.UserList { - // result = append(result, v) - // } - result := make([]*entity.User, 1) - for _, v := range follow { - result = append(result, &entity.User{ - Id: v, - }) - } - - return nil, result -} - // 查缓存 func ReadFollowListFromCache(user_id string) (error, []int64) { res, err := RedisClient.HGetAll(context.Background(), constants.FollowListPrefix+user_id).Result() diff --git a/applications/relationDomain/service/relation_follower_list.go b/applications/relationDomain/service/relation_follower_list.go index 47e8c389..9c9d72b1 100644 --- a/applications/relationDomain/service/relation_follower_list.go +++ b/applications/relationDomain/service/relation_follower_list.go @@ -5,71 +5,12 @@ import ( "fmt" "strconv" - "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" - "github.com/TremblingV5/DouTok/applications/relationDomain/dal/model" "github.com/TremblingV5/DouTok/applications/relationDomain/dal/query" - "github.com/TremblingV5/DouTok/kitex_gen/entity" "github.com/TremblingV5/DouTok/pkg/constants" - "github.com/cloudwego/kitex/pkg/klog" "github.com/go-redis/redis/v8" ) -type RelationFollowerListService struct { - ctx context.Context -} - -func NewRelationFollowerListService(ctx context.Context) *RelationFollowerListService { - return &RelationFollowerListService{ctx: ctx} -} - -func (s *RelationFollowerListService) RelationFollowerList(req *relationDomain.DoutokListRelationRequest) (error, []*entity.User) { - // 从 cache 读 - err, follower := ReadFollowerListFromCache(fmt.Sprintf("%d", req.UserId)) - if err != nil || follower == nil { - klog.Errorf("read follower list from cache error, err = %s", err) - // 从 db 读 - err, relationList := ReadFollowerListFromDB(req.UserId) - if err != nil { - klog.Errorf("read follower list from db error, err = %s", err) - return err, nil - } else { - // 添加 cache - err := WriteFollowerListToCache(fmt.Sprintf("%d", req.UserId), relationList) - if err != nil { - klog.Errorf("update follower list to cache error, err = %s", err) - } - // 为 follower 赋值 - list := make([]int64, len(relationList)) - for _, v := range relationList { - list = append(list, v.UserId) - } - follower = list - } - } - // 去用户服务查询 follow list 的 user 信息 - // request := new(userDomain.DoutokGetUserInfoRequest) - // request.UserId = follower - // resp, err := rpc.UserDomainRPCClient.GetUserInfo(context.Background(), request) - // if err != nil { - // return err, nil - // } - - // var result []*entity.User - // for _, v := range resp.UserList { - // result = append(result, v) - // } - - result := make([]*entity.User, 0) - for _, v := range follower { - result = append(result, &entity.User{ - Id: v, - }) - } - - return nil, result -} - // 查缓存 func ReadFollowerListFromCache(user_id string) (error, []int64) { res, err := RedisClient.HGetAll(context.Background(), constants.FollowerListPrefix+user_id).Result() diff --git a/applications/relationDomain/service/service.go b/applications/relationDomain/service/service.go index 768d58f9..8e4f149c 100644 --- a/applications/relationDomain/service/service.go +++ b/applications/relationDomain/service/service.go @@ -13,7 +13,7 @@ import ( func (s *Service) AddRelation(ctx context.Context, userId, toUserId int64) error { - err, followList := ReadFollowListFromCache(fmt.Sprint(userId)) + followList, err := s.followListRedis.Get(ctx, userId) if err != nil { return err } @@ -161,7 +161,7 @@ func (s *Service) RmRelation(ctx context.Context, userId, toUserId int64) error func (s *Service) ListFollowList(ctx context.Context, userId int64) ([]*entity.User, error) { // 从 cache 读 - err, follow := ReadFollowListFromCache(fmt.Sprintf("%d", userId)) + follow, err := s.followListRedis.Get(ctx, userId) if err != nil || follow == nil { klog.Errorf("read follow list from cache error, err = %s", err) // 从 db 读 @@ -208,7 +208,7 @@ func (s *Service) ListFollowList(ctx context.Context, userId int64) ([]*entity.U func (s *Service) ListFollowerList(ctx context.Context, userId int64) ([]*entity.User, error) { // 从 cache 读 - err, follower := ReadFollowerListFromCache(fmt.Sprintf("%d", userId)) + follower, err := s.followerListRedis.Get(ctx, userId) if err != nil || follower == nil { klog.Errorf("read follower list from cache error, err = %s", err) // 从 db 读 @@ -218,7 +218,7 @@ func (s *Service) ListFollowerList(ctx context.Context, userId int64) ([]*entity return nil, err } else { // 添加 cache - err := WriteFollowerListToCache(fmt.Sprintf("%d", userId), relationList) + err := s.followerListRedis.Set(ctx, userId, relationList) if err != nil { klog.Errorf("update follower list to cache error, err = %s", err) } @@ -311,7 +311,7 @@ func (s *Service) ListFriendList(ctx context.Context, userId int64) ([]*entity.U } func (s *Service) GetFollowCount(ctx context.Context, userId int64) (int64, error) { - err, follow := ReadFollowCountFromCache(fmt.Sprintf("%d", userId)) + follow, err := s.followCountRedis.Get(ctx, userId) if err != nil || follow == 0 { // 记录日志 klog.Errorf("read follow count from cache error, err = %s", err) @@ -323,7 +323,7 @@ func (s *Service) GetFollowCount(ctx context.Context, userId int64) (int64, erro follow = 0 } // 新增 cache 关注数 - err = WriteFollowCountToCache(fmt.Sprintf("%d", userId), follow) + err = s.followCountRedis.Set(ctx, userId, follow) if err != nil { // 记录日志 klog.Errorf("update follow count to cache error, err = %s", err) @@ -333,7 +333,7 @@ func (s *Service) GetFollowCount(ctx context.Context, userId int64) (int64, erro } func (s *Service) GetFollowerCount(ctx context.Context, userId int64) (int64, error) { - err, follower := ReadFollowerCountFromCache(fmt.Sprintf("%d", userId)) + follower, err := s.followerCountRedis.Get(ctx, userId) if err != nil || follower == 0 { // 记录日志 klog.Errorf("read follower count from cache error, err = %s", err) @@ -345,7 +345,7 @@ func (s *Service) GetFollowerCount(ctx context.Context, userId int64) (int64, er follower = 0 } // 新增 cache 粉丝数 - err = WriteFollowerCountToCache(fmt.Sprintf("%d", userId), follower) + err = s.followerCountRedis.Set(ctx, userId, follower) if err != nil { // 记录日志 klog.Errorf("update follower count to cache error, err = %s", err) diff --git a/applications/relationDomain/service/typedef.go b/applications/relationDomain/service/typedef.go index 6ca9c32d..d7a79255 100644 --- a/applications/relationDomain/service/typedef.go +++ b/applications/relationDomain/service/typedef.go @@ -2,14 +2,72 @@ package service import ( "context" + "github.com/TremblingV5/DouTok/applications/relation/service" + "github.com/TremblingV5/DouTok/applications/relationDomain/dal/model" + relationRepo "github.com/TremblingV5/DouTok/applications/relationDomain/dal/repository/relation" + "github.com/TremblingV5/DouTok/applications/relationDomain/pack" + "github.com/TremblingV5/DouTok/applications/relationDomain/redis/followCountRedis" + "github.com/TremblingV5/DouTok/applications/relationDomain/redis/followListRedis" + "github.com/TremblingV5/DouTok/applications/relationDomain/redis/followerCountRedis" + "github.com/TremblingV5/DouTok/applications/relationDomain/redis/followerListRedis" entity "github.com/TremblingV5/DouTok/kitex_gen/entity" + redishandle "github.com/TremblingV5/DouTok/pkg/redisHandle" ) type Service struct { + followListRedis FollowListRedis + followerListRedis FollowerListRedis + followCountRedis FollowCountRedis + followerCountRedis FollowerCountRedis + relationRepo RelationRepo } -func New() *Service { - return &Service{} +func New(repo *relationRepo.PersistRepository) *Service { + redisClient := redishandle.RedisClient{ + Client: service.RedisClient, + } + + return &Service{ + followListRedis: followListRedis.NewClient(&redisClient), + followerListRedis: followerListRedis.NewClient(&redisClient), + followCountRedis: followCountRedis.NewClient(&redisClient), + followerCountRedis: followerCountRedis.NewClient(&redisClient), + relationRepo: repo, + } +} + +type FollowListRedis interface { + Get(ctx context.Context, userId int64) ([]int64, error) + Set(ctx context.Context, userId int64, relations []*model.Relation) error +} + +type FollowerListRedis interface { + Get(ctx context.Context, userId int64) ([]int64, error) + Set(ctx context.Context, userId int64, relations []*model.Relation) error +} + +type FollowCountRedis interface { + Get(ctx context.Context, userId int64) (int64, error) + Set(ctx context.Context, userId int64, count int64) error + Del(ctx context.Context, userId int64) error +} + +type FollowerCountRedis interface { + Get(ctx context.Context, userId int64) (int64, error) + Set(ctx context.Context, userId int64, count int64) error + Del(ctx context.Context, userId int64) error +} + +type RelationRepo interface { + Save(relation *pack.Relation) error + SaveList(relationList []*pack.Relation) error + + //LoadOneByUserId(userId int64) (*pack.Relation, error) + //LoadOneByToUserId(toUserId int64) (*pack.Relation, error) + //LoadListByUserId(userId int64) ([]*pack.Relation, error) + //LoadListByToUserId(toUserId int64) ([]*pack.Relation, error) + //LoadCountByUserId(userId int64) (int64, error) + //LoadCountByToUserId(toUserId int64) (int64, error) } type IService interface { diff --git a/pkg/redisHandle/set.go b/pkg/redisHandle/set.go index 9b0b7537..aaa07b76 100644 --- a/pkg/redisHandle/set.go +++ b/pkg/redisHandle/set.go @@ -24,6 +24,10 @@ func (c *RedisClient) SetObj(ctx context.Context, key string, value any, expire return nil } +func (c *RedisClient) HDel(ctx context.Context, key string, hKey string) (int64, error) { + return c.Client.HDel(ctx, key, hKey).Result() +} + func (c *RedisClient) HSet(ctx context.Context, key string, hKey string, hValue string) error { return c.Client.HSet(ctx, key, hKey, hValue).Err() } From 1223c3346db5ea50bb392bb8e9ce1adba726ccfd Mon Sep 17 00:00:00 2001 From: xban Date: Wed, 27 Mar 2024 15:22:07 +0800 Subject: [PATCH 6/7] remove relationdomain handler ut --- .../relationDomain/handler/handler_test.go | 64 ------------------- 1 file changed, 64 deletions(-) delete mode 100644 applications/relationDomain/handler/handler_test.go diff --git a/applications/relationDomain/handler/handler_test.go b/applications/relationDomain/handler/handler_test.go deleted file mode 100644 index 07ffdca0..00000000 --- a/applications/relationDomain/handler/handler_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package handler - -import ( - "context" - "github.com/TremblingV5/DouTok/applications/relationDomain/service" - "github.com/TremblingV5/DouTok/kitex_gen/relationDomain" - "github.com/TremblingV5/DouTok/pkg/errno" - "math/rand" - "testing" - - "github.com/stretchr/testify/assert" -) - -func NewTestHandler() *Handler { - service.Init() - return New(service.New()) -} - -func TestRelationDomainHandler_ListRelation(t *testing.T) { - ctx := context.Background() - handler := NewTestHandler() - - t.Run("ListFollowList", func(t *testing.T) { - req := &relationDomain.DoutokListRelationRequest{ - ActionType: 0, - UserId: rand.Int63(), - } - - resp, err := handler.ListRelation(ctx, req) - - assert.NoError(t, err) - assert.NotNil(t, resp) - // assert.Equal(t, followList, resp.UserList) - assert.Equal(t, errno.SuccessCode, resp.StatusCode) - }) - - t.Run("ListFollowerList", func(t *testing.T) { - req := &relationDomain.DoutokListRelationRequest{ - ActionType: 1, - UserId: rand.Int63(), - } - - resp, err := handler.ListRelation(ctx, req) - - assert.NoError(t, err) - assert.NotNil(t, resp) - //assert.Equal(t, followerList, resp.UserList) - assert.Equal(t, errno.SuccessCode, resp.StatusCode) - }) - - t.Run("ListFriendList", func(t *testing.T) { - req := &relationDomain.DoutokListRelationRequest{ - ActionType: 2, - UserId: rand.Int63(), - } - - resp, err := handler.ListRelation(ctx, req) - - assert.NoError(t, err) - assert.NotNil(t, resp) - //assert.Equal(t, friendList, resp.UserList) - assert.Equal(t, errno.SuccessCode, resp.StatusCode) - }) -} From ebd0de381b605f07dc0f5acc39e96ccacf869e8b Mon Sep 17 00:00:00 2001 From: xban Date: Tue, 2 Apr 2024 14:51:18 +0800 Subject: [PATCH 7/7] fix: remove some comment code and change repo func --- .../dal/repository/relation/repository.go | 35 ++++++++++--------- .../relationDomain/service/typedef.go | 11 ++---- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/applications/relationDomain/dal/repository/relation/repository.go b/applications/relationDomain/dal/repository/relation/repository.go index 0a9be1e3..40063ad9 100644 --- a/applications/relationDomain/dal/repository/relation/repository.go +++ b/applications/relationDomain/dal/repository/relation/repository.go @@ -9,15 +9,8 @@ import ( ) type Repository interface { - Save(relation *pack.Relation) error - SaveList(relationList []*pack.Relation) error - - //LoadOneByUserId(userId int64) (*pack.Relation, error) - //LoadOneByToUserId(toUserId int64) (*pack.Relation, error) - //LoadListByUserId(userId int64) ([]*pack.Relation, error) - //LoadListByToUserId(toUserId int64) ([]*pack.Relation, error) - //LoadCountByUserId(userId int64) (int64, error) - //LoadCountByToUserId(toUserId int64) (int64, error) + CreateOrUpdate(relation *pack.Relation) error + CreateList(relationList []*pack.Relation) error } type PersistRepository struct { @@ -30,7 +23,15 @@ func New(db *gorm.DB) *PersistRepository { } } -func (p *PersistRepository) Save(rel *pack.Relation) error { +func packToModel(rel *pack.Relation) *model.Relation { + return &model.Relation{ + UserId: rel.UserId, + ToUserId: rel.ToUserId, + Status: int(rel.ActionType), + } +} + +func (p *PersistRepository) CreateOrUpdate(rel *pack.Relation) error { res, err := p.relation.Where( query.Relation.UserId.Eq(rel.UserId), query.Relation.ToUserId.Eq(rel.ToUserId), @@ -67,12 +68,14 @@ func (p *PersistRepository) Save(rel *pack.Relation) error { return nil } -func (p *PersistRepository) SaveList(relations []*pack.Relation) error { - for _, rel := range relations { - err := p.Save(rel) - if err != nil { - return err - } +func (p *PersistRepository) CreateList(relations []*pack.Relation) error { + models := make([]*model.Relation, 0, len(relations)) + for _, relation := range relations { + models = append(models, packToModel(relation)) + } + err := p.relation.CreateInBatches(models, len(models)) + if err != nil { + return err } return nil } diff --git a/applications/relationDomain/service/typedef.go b/applications/relationDomain/service/typedef.go index d7a79255..c74d8e34 100644 --- a/applications/relationDomain/service/typedef.go +++ b/applications/relationDomain/service/typedef.go @@ -59,15 +59,8 @@ type FollowerCountRedis interface { } type RelationRepo interface { - Save(relation *pack.Relation) error - SaveList(relationList []*pack.Relation) error - - //LoadOneByUserId(userId int64) (*pack.Relation, error) - //LoadOneByToUserId(toUserId int64) (*pack.Relation, error) - //LoadListByUserId(userId int64) ([]*pack.Relation, error) - //LoadListByToUserId(toUserId int64) ([]*pack.Relation, error) - //LoadCountByUserId(userId int64) (int64, error) - //LoadCountByToUserId(toUserId int64) (int64, error) + CreateOrUpdate(relation *pack.Relation) error + CreateList(relationList []*pack.Relation) error } type IService interface {