From 11f29280b1b155c152a68cb54394e2c03035b57d Mon Sep 17 00:00:00 2001 From: wangchuxiao Date: Mon, 8 Aug 2022 11:30:10 +0800 Subject: [PATCH] group hash --- cmd/open_im_api/docs/docs.go | 2 + cmd/open_im_api/docs/swagger.json | 2 + cmd/open_im_api/docs/swagger.yaml | 2 + cmd/open_im_api/main.go | 1 + go.mod | 4 +- go.sum | 20 +++- internal/api/group/group.go | 38 ++++++ internal/msg_transfer/logic/init.go | 4 +- internal/rpc/group/group.go | 145 ++++++++++++----------- internal/timed_task/clear_msg.go | 89 ++++++++++++++ internal/timed_task/init.go | 27 +---- internal/timed_task/timed_task.go | 37 +++--- pkg/base_info/group_api_struct.go | 11 ++ pkg/common/db/mongoModel.go | 41 +++++++ pkg/common/db/rocks_cache/rocks_cache.go | 49 +++++++- script/mongo-init.sh | 2 +- 16 files changed, 351 insertions(+), 123 deletions(-) create mode 100644 internal/timed_task/clear_msg.go diff --git a/cmd/open_im_api/docs/docs.go b/cmd/open_im_api/docs/docs.go index fb401960c..db9817fad 100644 --- a/cmd/open_im_api/docs/docs.go +++ b/cmd/open_im_api/docs/docs.go @@ -5931,7 +5931,9 @@ const docTemplate = `{ "base_info.GetGroupAllMemberReq": { "type": "object", "required": [ + "count", "groupID", + "offset", "operationID" ], "properties": { diff --git a/cmd/open_im_api/docs/swagger.json b/cmd/open_im_api/docs/swagger.json index dad0df3fe..e367d21cf 100644 --- a/cmd/open_im_api/docs/swagger.json +++ b/cmd/open_im_api/docs/swagger.json @@ -5923,7 +5923,9 @@ "base_info.GetGroupAllMemberReq": { "type": "object", "required": [ + "count", "groupID", + "offset", "operationID" ], "properties": { diff --git a/cmd/open_im_api/docs/swagger.yaml b/cmd/open_im_api/docs/swagger.yaml index c9b99dfb2..77f32fd30 100644 --- a/cmd/open_im_api/docs/swagger.yaml +++ b/cmd/open_im_api/docs/swagger.yaml @@ -918,7 +918,9 @@ definitions: operationID: type: string required: + - count - groupID + - offset - operationID type: object base_info.GetGroupAllMemberResp: diff --git a/cmd/open_im_api/main.go b/cmd/open_im_api/main.go index 9ff203659..e63749da3 100644 --- a/cmd/open_im_api/main.go +++ b/cmd/open_im_api/main.go @@ -106,6 +106,7 @@ func main() { groupRouterGroup.POST("/cancel_mute_group", group.CancelMuteGroup) groupRouterGroup.POST("/set_group_member_nickname", group.SetGroupMemberNickname) groupRouterGroup.POST("/set_group_member_info", group.SetGroupMemberInfo) + groupRouterGroup.POST("/get_group_abstract_info", group.GetGroupAbstractInfo) //groupRouterGroup.POST("/get_group_all_member_list_by_split", group.GetGroupAllMemberListBySplit) } superGroupRouterGroup := r.Group("/super_group") diff --git a/go.mod b/go.mod index 568aee953..57dee2392 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.2 // indirect github.com/pkg/errors v0.9.1 github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 + github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.2 github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe @@ -43,6 +44,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.428 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.428 github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20210325043845-84a0811633ca + github.com/xuri/excelize/v2 v2.6.0 go.etcd.io/etcd/api/v3 v3.5.4 go.etcd.io/etcd/client/v3 v3.5.4 go.mongodb.org/mongo-driver v1.8.3 @@ -50,7 +52,7 @@ require ( go.uber.org/multierr v1.7.0 // indirect go.uber.org/zap v1.19.1 // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect - golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb + golang.org/x/image v0.0.0-20211028202545-6944b10bf410 golang.org/x/net v0.0.0-20220622184535-263ec571b305 golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664 // indirect golang.org/x/tools v0.1.11 // indirect diff --git a/go.sum b/go.sum index 16b96bd44..161dba147 100644 --- a/go.sum +++ b/go.sum @@ -423,6 +423,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -481,8 +483,14 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= +github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= +github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= +github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -548,6 +556,12 @@ github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyh github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg/scram v1.0.3/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.3/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xuri/efp v0.0.0-20220407160117-ad0f7a785be8 h1:3X7aE0iLKJ5j+tz58BpvIZkXNV7Yq4jC93Z/rbN2Fxk= +github.com/xuri/efp v0.0.0-20220407160117-ad0f7a785be8/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.6.0 h1:m/aXAzSAqxgt74Nfd+sNzpzVKhTGl7+S9nbG4A57mF4= +github.com/xuri/excelize/v2 v2.6.0/go.mod h1:Q1YetlHesXEKwGFfeJn7PfEZz2IvHb6wdOeYjBxVcVs= +github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M= +github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -602,6 +616,7 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -616,8 +631,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk= -golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -691,6 +706,7 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220622184535-263ec571b305 h1:dAgbJ2SP4jD6XYfMNLVj0BF21jo2PjChrtGaAvF5M3I= golang.org/x/net v0.0.0-20220622184535-263ec571b305/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= diff --git a/internal/api/group/group.go b/internal/api/group/group.go index e79e781a8..13ee7c581 100644 --- a/internal/api/group/group.go +++ b/internal/api/group/group.go @@ -1272,3 +1272,41 @@ func SetGroupMemberInfo(c *gin.Context) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), " api args ", resp) c.JSON(http.StatusOK, resp) } + +func GetGroupAbstractInfo(c *gin.Context) { + var ( + req api.GetGroupAbstractInfoReq + resp api.GetGroupAbstractInfoResp + ) + if err := c.BindJSON(&req); err != nil { + log.NewError("0", "BindJSON failed ", err.Error()) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()}) + return + } + ok, opUserID, errInfo := token_verify.GetUserIDFromToken(c.Request.Header.Get("token"), req.OperationID) + if !ok { + errMsg := req.OperationID + " " + "GetUserIDFromToken failed " + errInfo + " token:" + c.Request.Header.Get("token") + log.NewError(req.OperationID, errMsg) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 500, "errMsg": errMsg}) + return + } + etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImGroupName, req.OperationID) + if etcdConn == nil { + errMsg := req.OperationID + "getcdv3.GetConn == nil" + log.NewError(req.OperationID, errMsg) + c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg}) + return + } + client := rpc.NewGroupClient(etcdConn) + respPb, err := client.GetGroupAbstractInfo(context.Background(), &rpc.GetGroupAbstractInfoReq{ + GroupID: req.GroupID, + OpUserID: opUserID, + OperationID: req.OperationID, + }) + if err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), " failed ", err.Error()) + c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": err.Error()}) + return + } + return +} diff --git a/internal/msg_transfer/logic/init.go b/internal/msg_transfer/logic/init.go index 38d0e5b66..44ce192a6 100644 --- a/internal/msg_transfer/logic/init.go +++ b/internal/msg_transfer/logic/init.go @@ -36,8 +36,8 @@ var ( func Init() { cmdCh = make(chan Cmd2Value, 10000) w = new(sync.Mutex) - persistentCH.Init() - historyCH.Init(cmdCh) + persistentCH.Init() // 订阅ws2mschat 消费到 mysql + historyCH.Init(cmdCh) // 订阅ws2mschat 如果可靠性存储 消费到 incrseq 再存入mongo 再push || 非可靠性 直接incr再push 初始化ws2mschat historyMongoCH.Init() onlineTopicStatus = OnlineTopicVacancy //offlineHistoryCH.Init(cmdCh) diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index f318e03bb..42887c6fd 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -34,10 +34,6 @@ type groupServer struct { etcdAddr []string } -func (s *groupServer) GetGroupAbstractInfo(c context.Context, req *pbGroup.GetGroupAbstractInfoReq) (*pbGroup.GetGroupAbstractInfoResp, error) { - panic("implement me") -} - func NewGroupServer(port int) *groupServer { log.NewPrivateLog(constant.LogFileName) return &groupServer{ @@ -148,7 +144,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR if req.GroupInfo.GroupType != constant.SuperGroup { //to group member for _, user := range req.InitMemberList { - us, err := imdb.GetUserByUserID(user.UserID) + us, err := rocksCache.GetUserInfoFromCache(user.UserID) if err != nil { log.NewError(req.OperationID, "GetUserByUserID failed ", err.Error(), user.UserID) continue @@ -168,7 +164,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR } okUserIDList = append(okUserIDList, user.UserID) } - group, err := imdb.GetGroupInfoByGroupID(groupId) + group, err := rocksCache.GetGroupInfoFromCache(groupId) if err != nil { log.NewError(req.OperationID, "GetGroupInfoByGroupID failed ", err.Error(), groupId) resp.ErrCode = constant.ErrDB.ErrCode @@ -176,7 +172,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR return resp, nil } utils.CopyStructFields(resp.GroupInfo, group) - memberCount, err := imdb.GetGroupMemberNumByGroupID(groupId) + memberCount, err := rocksCache.GetGroupMemberNumFromCache(groupId) resp.GroupInfo.MemberCount = uint32(memberCount) if err != nil { log.NewError(req.OperationID, "GetGroupMemberNumByGroupID failed ", err.Error(), groupId) @@ -245,7 +241,7 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbGroup.GetJo var resp pbGroup.GetJoinedGroupListResp for _, v := range joinedGroupList { var groupNode open_im_sdk.GroupInfo - num, err := imdb.GetGroupMemberNumByGroupID(v) + num, err := rocksCache.GetGroupMemberNumFromCache(v) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), v) continue @@ -463,7 +459,12 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite log.NewError(req.OperationID, "DelGroupMemberIDListFromCache rpc logic call failed ", cacheResp.String()) return &pbGroup.InviteUserToGroupResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}, nil } - + if err := rocksCache.DelGroupMemberListHashFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), req.GroupID, err.Error()) + } + if err := rocksCache.DelGroupMemberNumFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) + } if groupInfo.GroupType != constant.SuperGroup { for _, userID := range okUserIDList { err = rocksCache.DelJoinedGroupIDListFromCache(userID) @@ -687,6 +688,9 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou log.NewError(req.OperationID, "DelGroupMemberIDListFromCache rpc logic call failed ", cacheResp.String()) return &pbGroup.KickGroupMemberResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}, nil } + if err := rocksCache.DelGroupMemberListHashFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), req.GroupID, err.Error()) + } if groupInfo.GroupType != constant.SuperGroup { for _, userID := range okUserIDList { @@ -698,7 +702,9 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) } } - + if err := rocksCache.DelGroupMemberNumFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) + } chat.MemberKickedNotification(req, okUserIDList) } else { for _, userID := range okUserIDList { @@ -913,19 +919,15 @@ func (s *groupServer) GroupApplicationResponse(_ context.Context, req *pbGroup.G log.NewError(req.OperationID, "DelGroupMemberIDListFromCache rpc logic call failed ", cacheResp.String()) return &pbGroup.GroupApplicationResponseResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } - - //group, err := rocksCache.GetGroupInfoFromCache(req.GroupID) - //if err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), req.GroupID, err.Error()) - //} - //if group != nil { - // if group.GroupType != constant.SuperGroup { - // if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) - // } - // } - //} - + if err := rocksCache.DelGroupMemberListHashFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), req.GroupID, err.Error()) + } + if err := rocksCache.DelJoinedGroupIDListFromCache(req.FromUserID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), req.FromUserID, err.Error()) + } + if err := rocksCache.DelGroupMemberNumFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) + } chat.GroupApplicationAcceptedNotification(req) chat.MemberEnterNotification(req) } else if req.HandleResult == constant.GroupResponseRefuse { @@ -991,22 +993,16 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbGroup.JoinGroupReq) log.NewError(req.OperationID, "DelGroupMemberIDListFromCache rpc logic call failed ", cacheResp.String()) return &pbGroup.JoinGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } - //for _, userID := range okUserIDList { - // err = rocksCache.DelJoinedGroupIDListFromCache(userID) - // if err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), userID) - // } - //} err = rocksCache.DelJoinedGroupIDListFromCache(req.OpUserID) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error()) } - - //err = rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID) - //if err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error()) - //} - + if err := rocksCache.DelGroupMemberListHashFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), req.GroupID, err.Error()) + } + if err := rocksCache.DelGroupMemberNumFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) + } chat.MemberEnterDirectlyNotification(req.GroupID, req.OpUserID, req.OperationID) log.NewInfo(req.OperationID, "JoinGroup rpc return ") return &pbGroup.JoinGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: 0, ErrMsg: ""}}, nil @@ -1113,17 +1109,19 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbGroup.QuitGroupReq) log.NewError(req.OperationID, "DelGroupMemberIDListFromCache rpc logic call failed ", cacheResp.String()) return &pbGroup.QuitGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } - + if err := rocksCache.DelGroupMemberListHashFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), req.GroupID, err.Error()) + } if groupInfo.GroupType != constant.SuperGroup { - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) - //} - if err := rocksCache.DelGroupMemberInfoFromCache(req.GroupID, req.OpUserID); err != nil { - log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) - } if err := rocksCache.DelJoinedGroupIDListFromCache(req.OpUserID); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.OpUserID) } + if err := rocksCache.DelGroupMemberNumFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupId) + } + if err := rocksCache.DelGroupMemberInfoFromCache(req.GroupID, req.OpUserID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) + } chat.MemberQuitNotification(req) } else { if err := rocksCache.DelJoinedSuperGroupIDListFromCache(req.OpUserID); err != nil { @@ -1322,9 +1320,6 @@ func (s *groupServer) TransferGroupOwner(_ context.Context, req *pbGroup.Transfe log.NewError(req.OperationID, "UpdateGroupMemberInfo failed ", groupMemberInfo) return &pbGroup.TransferGroupOwnerResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), req.GroupID, err.Error()) - //} err = rocksCache.DelGroupMemberInfoFromCache(req.GroupID, req.NewOwnerUserID) if err != nil { log.NewError(req.OperationID, "DelGroupMemberInfoFromCache failed ", req.GroupID, req.NewOwnerUserID) @@ -1607,9 +1602,13 @@ func (s *groupServer) RemoveGroupMembersCMS(_ context.Context, req *pbGroup.Remo log.NewError(req.OperationID, "DelGroupMemberIDListFromCache rpc logic call failed ", cacheResp.String()) return resp, http.WrapError(constant.ErrDB) } - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupId); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupId) - //} + if err := rocksCache.DelGroupMemberListHashFromCache(req.GroupId); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupId) + } + if err := rocksCache.DelGroupMemberNumFromCache(req.GroupId); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupId) + } + for _, userID := range resp.Success { if err := rocksCache.DelGroupMemberInfoFromCache(req.GroupId, userID); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupId, userID) @@ -1674,9 +1673,12 @@ func (s *groupServer) AddGroupMembersCMS(_ context.Context, req *pbGroup.AddGrou log.NewError(req.OperationId, "DelGroupMemberIDListFromCache rpc logic call failed ", cacheResp.String()) return resp, http.WrapError(constant.ErrDB) } - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupId); err != nil { - // log.NewError(req.OperationId, utils.GetSelfFuncName(), err.Error(), req.GroupId) - //} + if err := rocksCache.DelGroupMemberListHashFromCache(req.GroupId); err != nil { + log.NewError(req.OperationId, utils.GetSelfFuncName(), err.Error(), req.GroupId) + } + if err := rocksCache.DelGroupMemberNumFromCache(req.GroupId); err != nil { + log.NewError(req.OperationId, utils.GetSelfFuncName(), err.Error(), req.GroupId) + } chat.MemberInvitedNotification(req.OperationId, req.GroupId, req.OpUserId, "admin add you to group", resp.Success) return resp, nil @@ -1798,9 +1800,9 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbGroup.DismissGrou log.NewError(req.OperationID, "DelGroupMemberIDListFromCache rpc logic call failed ", cacheResp.String()) return &pbGroup.DismissGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: cacheResp.CommonResp.ErrCode, ErrMsg: cacheResp.CommonResp.ErrMsg}}, nil } - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) - //} + if err := rocksCache.DelGroupInfoFromCache(req.GroupID); err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) + } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "rpc return ", pbGroup.CommonResp{ErrCode: 0, ErrMsg: ""}) return &pbGroup.DismissGroupResp{CommonResp: &pbGroup.CommonResp{ErrCode: 0, ErrMsg: ""}}, nil } @@ -1846,9 +1848,6 @@ func (s *groupServer) MuteGroupMember(ctx context.Context, req *pbGroup.MuteGrou log.Error(req.OperationID, "UpdateGroupMemberInfo failed ", err.Error(), groupMemberInfo) return &pbGroup.MuteGroupMemberResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) - //} if err := rocksCache.DelGroupMemberInfoFromCache(req.GroupID, req.UserID); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) } @@ -1893,9 +1892,6 @@ func (s *groupServer) CancelMuteGroupMember(ctx context.Context, req *pbGroup.Ca log.Error(req.OperationID, "UpdateGroupMemberInfo failed ", err.Error(), groupMemberInfo) return &pbGroup.CancelMuteGroupMemberResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) - //} if err := rocksCache.DelGroupMemberInfoFromCache(req.GroupID, req.UserID); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) } @@ -2016,9 +2012,6 @@ func (s *groupServer) SetGroupMemberNickname(ctx context.Context, req *pbGroup.S log.Error(req.OperationID, errMsg) return &pbGroup.SetGroupMemberNicknameResp{CommonResp: &pbGroup.CommonResp{ErrCode: constant.ErrDB.ErrCode, ErrMsg: constant.ErrDB.ErrMsg}}, nil } - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) - //} if err := rocksCache.DelGroupMemberInfoFromCache(req.GroupID, req.UserID); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) } @@ -2054,9 +2047,6 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGr resp.CommonResp.ErrMsg = constant.ErrDB.ErrMsg + ":" + err.Error() return resp, nil } - //if err := rocksCache.DelAllGroupMembersInfoFromCache(req.GroupID); err != nil { - // log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID) - //} if err := rocksCache.DelGroupMemberInfoFromCache(req.GroupID, req.UserID); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), err.Error(), req.GroupID, req.UserID) } @@ -2075,3 +2065,26 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGr log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String()) return resp, nil } + +func (s *groupServer) GetGroupAbstractInfo(c context.Context, req *pbGroup.GetGroupAbstractInfoReq) (*pbGroup.GetGroupAbstractInfoResp, error) { + log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) + resp := &pbGroup.GetGroupAbstractInfoResp{CommonResp: &pbGroup.CommonResp{}} + hashCode, err := rocksCache.GetGroupMemberListHashFromCache(req.GroupID) + if err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetGroupMemberListHashFromCache failed", req.GroupID, err.Error()) + resp.CommonResp.ErrCode = constant.ErrDB.ErrCode + resp.CommonResp.ErrMsg = err.Error() + return resp, nil + } + resp.GroupMemberListHash = hashCode + num, err := rocksCache.GetGroupMemberNumFromCache(req.GroupID) + if err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetGroupMemberNumByGroupID failed", req.GroupID, err.Error()) + resp.CommonResp.ErrCode = constant.ErrDB.ErrCode + resp.CommonResp.ErrMsg = err.Error() + return resp, nil + } + resp.GroupMemberNumber = int32(num) + log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", resp.String()) + return resp, nil +} diff --git a/internal/timed_task/clear_msg.go b/internal/timed_task/clear_msg.go new file mode 100644 index 000000000..6cb3cba79 --- /dev/null +++ b/internal/timed_task/clear_msg.go @@ -0,0 +1,89 @@ +package timedTask + +import ( + "Open_IM/pkg/common/config" + "Open_IM/pkg/common/constant" + "Open_IM/pkg/common/db" + "Open_IM/pkg/common/log" + server_api_params "Open_IM/pkg/proto/sdk_ws" + "Open_IM/pkg/utils" + "github.com/golang/protobuf/proto" + "strconv" + "strings" +) + +const oldestList = 0 +const newestList = -1 + +func DeleteMongoMsgAndResetRedisSeq(operationID, ID string, diffusionType int) error { + // -1 表示从当前最早的一个开始 + var delMsgIDList []string + minSeq, err := deleteMongoMsg(operationID, ID, oldestList, &delMsgIDList) + if err != nil { + return utils.Wrap(err, "") + } + log.NewDebug(operationID, utils.GetSelfFuncName(), "delMsgIDList: ", delMsgIDList) + if diffusionType == constant.WriteDiffusion { + err = db.DB.SetUserMinSeq(ID, minSeq) + } else if diffusionType == constant.ReadDiffusion { + err = db.DB.SetGroupMinSeq(ID, minSeq) + } + return err +} + +// recursion +func deleteMongoMsg(operationID string, ID string, index int64, IDList *[]string) (uint32, error) { + // 从最旧的列表开始找 + msgs, err := db.DB.GetUserMsgListByIndex(ID, index) + if err != nil { + return 0, utils.Wrap(err, "GetUserMsgListByIndex failed") + } + log.NewDebug(operationID, utils.GetSelfFuncName(), "get msgs: ", msgs.UID) + for i, msg := range msgs.Msg { + // 找到列表中不需要删除的消息了 + if msg.SendTime+int64(config.Config.Mongo.DBRetainChatRecords) > utils.GetCurrentTimestampByMill() { + if len(*IDList) > 0 { + err := db.DB.DelMongoMsgs(*IDList) + if err != nil { + return 0, utils.Wrap(err, "DelMongoMsgs failed") + } + } + minSeq := getDelMaxSeqByIDList(*IDList) + if i > 0 { + msgPb := &server_api_params.MsgData{} + err = proto.Unmarshal(msg.Msg, msgPb) + if err != nil { + log.NewError(operationID, utils.GetSelfFuncName(), err.Error(), ID, index) + } else { + err = db.DB.ReplaceMsgToBlankByIndex(msgs.UID, i-1) + if err != nil { + log.NewError(operationID, utils.GetSelfFuncName(), err.Error(), msgs.UID, i) + return minSeq, nil + } + minSeq = msgPb.Seq - 1 + } + } + return minSeq, nil + } + } + *IDList = append(*IDList, msgs.UID) + // 没有找到 代表需要全部删除掉 继续查找下一个比较旧的列表 + seq, err := deleteMongoMsg(operationID, utils.GetSelfFuncName(), index-1, IDList) + if err != nil { + return 0, utils.Wrap(err, "deleteMongoMsg failed") + } + return seq, nil +} + +func getDelMaxSeqByIDList(IDList []string) uint32 { + if len(IDList) == 0 { + return 0 + } + l := strings.Split(IDList[len(IDList)-1], ":") + index, _ := strconv.Atoi(l[len(l)-1]) + if index == 0 { + // 4999 + return uint32(db.GetSingleGocMsgNum()) - 1 + } // 5000 + return (uint32(db.GetSingleGocMsgNum()) - 1) + uint32(index*db.GetSingleGocMsgNum()) +} diff --git a/internal/timed_task/init.go b/internal/timed_task/init.go index 8ee5d9452..fe4e214b0 100644 --- a/internal/timed_task/init.go +++ b/internal/timed_task/init.go @@ -1,26 +1 @@ -package timed_task - -type TimeTask struct { - delMgoChatChan chan bool -} - -var timeTask TimeTask - -func GetInstance() *TimeTask { - if timeTask.delMgoChatChan == nil { - timeTask.delMgoChatChan = make(chan bool) - go func() { - timeTask.delMgoChatChan <- true - }() - } - return &timeTask -} - -func (t *TimeTask) Run() { - for { - select { - case <-t.delMgoChatChan: - t.timedDeleteUserChat() - } - } -} +package timedTask diff --git a/internal/timed_task/timed_task.go b/internal/timed_task/timed_task.go index 5b0264123..2498c730b 100644 --- a/internal/timed_task/timed_task.go +++ b/internal/timed_task/timed_task.go @@ -1,26 +1,23 @@ -package timed_task +package timedTask import ( - "Open_IM/pkg/common/db" - "time" + "Open_IM/pkg/common/constant" + "Open_IM/pkg/common/log" + "Open_IM/pkg/utils" + "github.com/robfig/cron/v3" ) -func (t *TimeTask) timedDeleteUserChat() { - now := time.Now() - next := now.Add(time.Hour * 24) - next = time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location()) - tm := time.NewTimer(next.Sub(now)) - - <-tm.C - - count, _ := db.DB.MgoUserCount() - for i := 0; i < count; i++ { - time.Sleep(10 * time.Millisecond) - uid, _ := db.DB.MgoSkipUID(i) - db.DB.DelUserChatMongo2(uid) +func main() { + log.NewInfo(utils.OperationIDGenerator(), "start cron task") + c := cron.New() + _, err := c.AddFunc("30 3-6,20-23 * * *", func() { + operationID := utils.OperationIDGenerator() + if err := DeleteMongoMsgAndResetRedisSeq(operationID, "", constant.ReadDiffusion); err != nil { + log.NewError(operationID) + } + }) + if err != nil { + panic(err) } - - go func() { - t.delMgoChatChan <- true - }() + c.Start() } diff --git a/pkg/base_info/group_api_struct.go b/pkg/base_info/group_api_struct.go index 896f40438..8918b852c 100644 --- a/pkg/base_info/group_api_struct.go +++ b/pkg/base_info/group_api_struct.go @@ -289,3 +289,14 @@ type SetGroupMemberInfoReq struct { type SetGroupMemberInfoResp struct { CommResp } + +type GetGroupAbstractInfoReq struct { + OperationID string `json:"operationID"` + GroupID string `json:"groupID"` +} + +type GetGroupAbstractInfoResp struct { + CommResp + GroupMemberNumber int32 `json:"groupMemberNumber"` + GroupMemberListHash uint64 `json:"groupMemberListHash"` +} diff --git a/pkg/common/db/mongoModel.go b/pkg/common/db/mongoModel.go index fdecf5e8f..083d89b2a 100644 --- a/pkg/common/db/mongoModel.go +++ b/pkg/common/db/mongoModel.go @@ -46,6 +46,7 @@ type MsgInfo struct { type UserChat struct { UID string + //ListIndex int `bson:"index"` Msg []MsgInfo } @@ -258,6 +259,45 @@ func (d *DataBases) GetMsgBySeqList(uid string, seqList []uint32, operationID st return seqMsg, nil } +func (d *DataBases) GetUserMsgListByIndex(ID string, index int64) (msg *UserChat, err error) { + ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) + c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat) + regex := fmt.Sprintf("^%s", ID) + findOpts := options.Find().SetLimit(1).SetSkip(index).SetSort(bson.M{"$regex": regex}) + msg = &UserChat{} + cursor, err := c.Find(ctx, bson.M{"uid": bson.M{"$regex": regex}}, findOpts) + if err != nil { + return nil, err + } + err = cursor.Decode(&msg) + return msg, err +} + +func (d *DataBases) DelMongoMsgs(IDList []string) error { + ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) + c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat) + _, err := c.DeleteMany(ctx, bson.M{"uid": bson.M{"$in": IDList}}) + return err +} + +func (d *DataBases) ReplaceMsgToBlankByIndex(suffixID string, index int) error { + ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) + c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cChat) + userChat := &UserChat{} + err := c.FindOne(ctx, bson.M{"uid": suffixID}).Decode(&userChat) + if err != nil { + return err + } + for i, msg := range userChat.Msg { + if i <= index { + msg.Msg = nil + msg.SendTime = 0 + } + } + _, err = c.UpdateOne(ctx, bson.M{"uid": suffixID}, userChat) + return err +} + func (d *DataBases) GetMsgBySeqListMongo2(uid string, seqList []uint32, operationID string) (seqMsg []*open_im_sdk.MsgData, err error) { var hasSeqList []uint32 singleCount := 0 @@ -1192,6 +1232,7 @@ func isNotContainInt32(target uint32, List []uint32) bool { func indexGen(uid string, seqSuffix uint32) string { return uid + ":" + strconv.FormatInt(int64(seqSuffix), 10) } + func superGroupIndexGen(groupID string, seqSuffix uint32) string { return "super_group_" + groupID + ":" + strconv.FormatInt(int64(seqSuffix), 10) } diff --git a/pkg/common/db/rocks_cache/rocks_cache.go b/pkg/common/db/rocks_cache/rocks_cache.go index c23a8777c..1304aeedf 100644 --- a/pkg/common/db/rocks_cache/rocks_cache.go +++ b/pkg/common/db/rocks_cache/rocks_cache.go @@ -10,6 +10,9 @@ import ( "encoding/json" "errors" "fmt" + "math/big" + "sort" + "strconv" "time" ) @@ -27,6 +30,8 @@ const ( allDepartmentCache = "ALL_DEPARTMENT_CACHE:" allDepartmentMemberCache = "ALL_DEPARTMENT_MEMBER_CACHE:" joinedSuperGroupListCache = "JOINED_SUPER_GROUP_LIST_CACHE:" + groupMemberListHashCache = "GROUP_MEMBER_LIST_HASH_CACHE:" + groupMemberNumCache = "GROUP_MEMBER_NUM_CACHE:" ) func init() { @@ -374,7 +379,7 @@ func GetJoinedSuperGroupListFromCache(userID string) ([]string, error) { bytes, err := json.Marshal(userToSuperGroup.GroupIDList) return string(bytes), utils.Wrap(err, "") } - joinedSuperGroupListStr, err := db.DB.Rc.Fetch(joinedSuperGroupListCache+userID, time.Second, getJoinedSuperGroupIDList) + joinedSuperGroupListStr, err := db.DB.Rc.Fetch(joinedSuperGroupListCache+userID, time.Second*30*60, getJoinedSuperGroupIDList) var joinedSuperGroupList []string err = json.Unmarshal([]byte(joinedSuperGroupListStr), &joinedSuperGroupList) return joinedSuperGroupList, err @@ -385,10 +390,44 @@ func DelJoinedSuperGroupIDListFromCache(userID string) error { return err } -func GetSuperGroupMemberIDListFromCache(groupID string) ([]string, error) { - return GetGroupMemberIDListFromCache(groupID) +func GetGroupMemberListHashFromCache(groupID string) (uint64, error) { + generateHash := func() (string, error) { + groupMemberIDList, err := GetGroupMemberIDListFromCache(groupID) + if err != nil { + return "", utils.Wrap(err, "") + } + sort.Strings(groupMemberIDList) + var all string + for _, v := range groupMemberIDList { + all += v + } + bi := big.NewInt(0) + bi.SetString(utils.Md5(all)[0:8], 16) + return strconv.Itoa(int(bi.Uint64())), nil + } + hashCode, err := db.DB.Rc.Fetch(groupMemberListHashCache+groupID, time.Second*30*60, generateHash) + hashCodeUint64, err := strconv.Atoi(hashCode) + return uint64(hashCodeUint64), err } -func DelSuperGroupMemberIDListFromCache(groupID string) error { - return DelGroupMemberIDListFromCache(groupID) +func DelGroupMemberListHashFromCache(groupID string) error { + err := db.DB.Rc.TagAsDeleted(groupMemberListHashCache + groupID) + return err +} + +func GetGroupMemberNumFromCache(groupID string) (int64, error) { + getGroupMemberNum := func() (string, error) { + num, err := imdb.GetGroupMemberNumByGroupID(groupID) + if err != nil { + return "", utils.Wrap(err, "") + } + return strconv.Itoa(int(num)), nil + } + groupMember, err := db.DB.Rc.Fetch(groupMemberNumCache+groupID, time.Second*30*60, getGroupMemberNum) + num, err := strconv.Atoi(groupMember) + return int64(num), err +} + +func DelGroupMemberNumFromCache(groupID string) error { + return db.DB.Rc.TagAsDeleted(groupMemberNumCache + groupID) } diff --git a/script/mongo-init.sh b/script/mongo-init.sh index ad9c84428..3d1faa60b 100644 --- a/script/mongo-init.sh +++ b/script/mongo-init.sh @@ -6,7 +6,7 @@ db.createUser({ user: "$MONGO_USERNAME", pwd: "$MONGO_PASSWORD", roles: [ - { role: 'readWrite', db: '$MONGO_INITDB_DATABASE' } + { role: 'root', db: '$MONGO_INITDB_DATABASE' } ] }) EOF