diff --git a/.github/workflows/cleanup-after-milestone-prs-merged.yml b/.github/workflows/cleanup-after-milestone-prs-merged.yml index 4e9cc403d..8a3e381d6 100644 --- a/.github/workflows/cleanup-after-milestone-prs-merged.yml +++ b/.github/workflows/cleanup-after-milestone-prs-merged.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.2.0 - name: Get the PR title and extract PR numbers id: extract_pr_numbers @@ -36,15 +36,6 @@ jobs: echo "proceed=false" >> $GITHUB_OUTPUT fi - - name: Delete branch after PR close - if: steps.extract_pr_numbers.outputs.proceed == 'true' || contains(github.event.pull_request.labels.*.name, 'milestone-merge') - run: | - BRANCH_NAME="${{ github.event.pull_request.head.ref }}" - echo "Branch to delete: $BRANCH_NAME" - git push origin --delete "$BRANCH_NAME" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Use extracted PR numbers and label PRs if: (steps.extract_pr_numbers.outputs.proceed == 'true' || contains(github.event.pull_request.labels.*.name, 'milestone-merge')) && github.event.pull_request.merged == true run: | @@ -63,3 +54,12 @@ jobs: done env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Delete branch after PR close + if: steps.extract_pr_numbers.outputs.proceed == 'true' || contains(github.event.pull_request.labels.*.name, 'milestone-merge') + run: | + BRANCH_NAME="${{ github.event.pull_request.head.ref }}" + echo "Branch to delete: $BRANCH_NAME" + git push origin --delete "$BRANCH_NAME" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/go.mod b/go.mod index f3535b30d..4e8fcbb4b 100644 --- a/go.mod +++ b/go.mod @@ -57,4 +57,5 @@ require ( golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/conversation_msg/api.go b/internal/conversation_msg/api.go index 282c739cd..8a6af4e6e 100644 --- a/internal/conversation_msg/api.go +++ b/internal/conversation_msg/api.go @@ -520,12 +520,16 @@ func (c *Conversation) SendMessage(ctx context.Context, s *sdk_struct.MsgStruct, break } name := s.FileElem.FileName + if name == "" { name = s.FileElem.FilePath } if name == "" { name = fmt.Sprintf("msg_file_%s.unknown", s.ClientMsgID) } + + delFile = append(delFile, s.FileElem.FilePath) + res, err := c.file.UploadFile(ctx, &file.UploadFileReq{ ContentType: content_type.GetType(s.FileElem.FileType, filepath.Ext(s.FileElem.FilePath), filepath.Ext(s.FileElem.FileName)), Filepath: s.FileElem.FilePath, @@ -657,7 +661,7 @@ func (c *Conversation) SendMessageNotOss(ctx context.Context, s *sdk_struct.MsgS } func (c *Conversation) sendMessageToServer(ctx context.Context, s *sdk_struct.MsgStruct, lc *model_struct.LocalConversation, callback open_im_sdk_callback.SendMsgCallBack, - delFile []string, offlinePushInfo *sdkws.OfflinePushInfo, options map[string]bool, isOnlineOnly bool) (*sdk_struct.MsgStruct, error) { + delFiles []string, offlinePushInfo *sdkws.OfflinePushInfo, options map[string]bool, isOnlineOnly bool) (*sdk_struct.MsgStruct, error) { if isOnlineOnly { utils.SetSwitchFromOptions(options, constant.IsHistory, false) utils.SetSwitchFromOptions(options, constant.IsPersistent, false) @@ -709,13 +713,14 @@ func (c *Conversation) sendMessageToServer(ctx context.Context, s *sdk_struct.Ms s.ServerMsgID = sendMsgResp.ServerMsgID go func() { //remove media cache file - for _, v := range delFile { - err := os.Remove(v) + for _, file := range delFiles { + err := os.Remove(file) if err != nil { - // log.Error("", "remove failed,", err.Error(), v) + log.ZError(ctx, "delete temp File is failed", err, "filePath", file) } - // log.Debug("", "remove file: ", v) + // log.ZDebug(ctx, "remove temp file:", "file", file) } + c.updateMsgStatusAndTriggerConversation(ctx, sendMsgResp.ClientMsgID, sendMsgResp.ServerMsgID, sendMsgResp.SendTime, constant.MsgStatusSendSuccess, s, lc, isOnlineOnly) }() return s, nil diff --git a/internal/conversation_msg/message_check.go b/internal/conversation_msg/message_check.go index 5c14319b6..88f3e3c53 100644 --- a/internal/conversation_msg/message_check.go +++ b/internal/conversation_msg/message_check.go @@ -377,6 +377,7 @@ func (c *Conversation) groupHandle(ctx context.Context, self, others []*model_st } for _, chatLog := range allMessage { if g, ok := groupMap[chatLog.SendID]; ok { // If group member info is successfully retrieved + log.ZDebug(ctx, "find in GetGroupMemberNameAndFaceURL", "sendID", chatLog.SendID, "faceURL", g.FaceURL, "nickName", g.Nickname) if g.FaceURL != "" && g.Nickname != "" { chatLog.SenderFaceURL = g.FaceURL chatLog.SenderNickname = g.Nickname @@ -386,6 +387,7 @@ func (c *Conversation) groupHandle(ctx context.Context, self, others []*model_st if err != nil { log.ZWarn(ctx, "getUserNameAndFaceURL error", err, "senderID", chatLog.SendID) } else if faceURL != "" && name != "" { + log.ZDebug(ctx, "find in getUserNameAndFaceURL", "sendID", chatLog.SendID, "faceURL", faceURL, "nickName", name) chatLog.SenderFaceURL = faceURL chatLog.SenderNickname = name } diff --git a/internal/group/cache.go b/internal/group/cache.go index 6ef8a1e6f..8e9e5c397 100644 --- a/internal/group/cache.go +++ b/internal/group/cache.go @@ -3,6 +3,7 @@ package group import ( "context" "github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct" + "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" ) @@ -20,13 +21,14 @@ func (g *Group) GetGroupMembersInfoFunc(ctx context.Context, groupID string, use for _, userID := range userIDs { key := g.buildGroupMemberKey(groupID, userID) - if member, ok := g.groupMemberCache.Load(groupID); ok { - res[key] = member + if member, ok := g.groupMemberCache.Load(key); ok { + res[userID] = member } else { missingKeys = append(missingKeys, userIDs...) } } + log.ZDebug(ctx, "GetGroupMembersInfoFunc fetch", "missingKeys", missingKeys) fetchData, err := fetchFunc(ctx, missingKeys) if err != nil { return nil, err @@ -34,7 +36,7 @@ func (g *Group) GetGroupMembersInfoFunc(ctx context.Context, groupID string, use for i, data := range fetchData { key := g.buildGroupMemberKey(groupID, data.UserID) - res[key] = fetchData[i] + res[data.UserID] = fetchData[i] g.groupMemberCache.Store(key, fetchData[i]) } diff --git a/internal/group/group.go b/internal/group/group.go index 36d7248ad..3783a3c72 100644 --- a/internal/group/group.go +++ b/internal/group/group.go @@ -156,6 +156,7 @@ func (g *Group) initSyncer() { return g.db.DeleteGroupMember(ctx, value.GroupID, value.UserID) }), syncer.WithUpdate[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(ctx context.Context, server, local *model_struct.LocalGroupMember) error { + g.groupMemberCache.Delete(g.buildGroupMemberKey(server.GroupID, server.UserID)) return g.db.UpdateGroupMember(ctx, server) }), syncer.WithUUID[*model_struct.LocalGroupMember, group.GetGroupMemberListResp, [2]string](func(value *model_struct.LocalGroupMember) [2]string { diff --git a/internal/interaction/msg_sync.go b/internal/interaction/msg_sync.go index ebd65247e..4b3e9d40f 100644 --- a/internal/interaction/msg_sync.go +++ b/internal/interaction/msg_sync.go @@ -88,8 +88,15 @@ func (m *MsgSyncer) loadSeq(ctx context.Context) error { log.ZError(ctx, "get conversation id list failed", err) return err } + if len(conversationIDList) == 0 { - m.reinstalled = true + version, err := m.db.GetAppSDKVersion(ctx) + if err != nil { + return err + } + if !version.Installed { + m.reinstalled = true + } } // TODO With a large number of sessions, this could potentially cause blocking and needs optimization. @@ -248,6 +255,11 @@ func (m *MsgSyncer) compareSeqsAndBatchSync(ctx context.Context, maxSeqToSync ma } } defer func() { + if err := m.db.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{ + Installed: true, + }); err != nil { + log.ZError(ctx, "SetAppSDKVersion err", err) + } m.reinstalled = false }() _ = m.syncAndTriggerReinstallMsgs(m.ctx, needSyncSeqMap, pullNums) @@ -269,24 +281,24 @@ func (m *MsgSyncer) compareSeqsAndBatchSync(ctx context.Context, maxSeqToSync ma // startSync checks if the sync is already in progress. // If syncing is in progress, it returns false. Otherwise, it starts syncing and returns true. -func (ms *MsgSyncer) startSync() bool { - ms.isSyncingLock.Lock() - defer ms.isSyncingLock.Unlock() +func (m *MsgSyncer) startSync() bool { + m.isSyncingLock.Lock() + defer m.isSyncingLock.Unlock() - if ms.isSyncing { + if m.isSyncing { // If already syncing, return false return false } // Set syncing to true and start the sync - ms.isSyncing = true + m.isSyncing = true // Create a goroutine that waits for 5 seconds and then sets isSyncing to false go func() { time.Sleep(5 * time.Second) - ms.isSyncingLock.Lock() - ms.isSyncing = false - ms.isSyncingLock.Unlock() + m.isSyncingLock.Lock() + m.isSyncing = false + m.isSyncingLock.Unlock() }() return true diff --git a/internal/relation/relation.go b/internal/relation/relation.go index a05869a25..962291cea 100644 --- a/internal/relation/relation.go +++ b/internal/relation/relation.go @@ -36,7 +36,7 @@ type Relation struct { db db_interface.DataBase user *user.User friendSyncer *syncer.Syncer[*model_struct.LocalFriend, relation.GetPaginationFriendsResp, [2]string] - blockSyncer *syncer.Syncer[*model_struct.LocalBlack, syncer.NoResp, [2]string] + blackSyncer *syncer.Syncer[*model_struct.LocalBlack, syncer.NoResp, [2]string] requestRecvSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string] requestSendSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string] conversationCh chan common.Cmd2Value @@ -53,6 +53,7 @@ func (r *Relation) initSyncer() { return r.db.DeleteFriendDB(ctx, value.FriendUserID) }), syncer.WithUpdate[*model_struct.LocalFriend, relation.GetPaginationFriendsResp, [2]string](func(ctx context.Context, server, local *model_struct.LocalFriend) error { + r.user.UserCache.Delete(server.FriendUserID) return r.db.UpdateFriend(ctx, server) }), syncer.WithUUID[*model_struct.LocalFriend, relation.GetPaginationFriendsResp, [2]string](func(value *model_struct.LocalFriend) [2]string { @@ -132,7 +133,7 @@ func (r *Relation) initSyncer() { syncer.WithFullSyncLimit[*model_struct.LocalFriend, relation.GetPaginationFriendsResp, [2]string](friendSyncLimit), ) - r.blockSyncer = syncer.New[*model_struct.LocalBlack, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalBlack) error { + r.blackSyncer = syncer.New[*model_struct.LocalBlack, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalBlack) error { return r.db.InsertBlack(ctx, value) }, func(ctx context.Context, value *model_struct.LocalBlack) error { return r.db.DeleteBlack(ctx, value.BlockUserID) diff --git a/internal/relation/sync.go b/internal/relation/sync.go index 0390be2f8..48a515101 100644 --- a/internal/relation/sync.go +++ b/internal/relation/sync.go @@ -104,7 +104,7 @@ func (r *Relation) SyncAllBlackList(ctx context.Context) error { return err } log.ZDebug(ctx, "black from local", "data", localData) - return r.blockSyncer.Sync(ctx, datautil.Batch(ServerBlackToLocalBlack, serverData), localData, nil) + return r.blackSyncer.Sync(ctx, datautil.Batch(ServerBlackToLocalBlack, serverData), localData, nil) } func (r *Relation) SyncAllBlackListWithoutNotice(ctx context.Context) error { @@ -118,7 +118,7 @@ func (r *Relation) SyncAllBlackListWithoutNotice(ctx context.Context) error { return err } log.ZDebug(ctx, "black from local", "data", localData) - return r.blockSyncer.Sync(ctx, datautil.Batch(ServerBlackToLocalBlack, serverData), localData, nil, false, true) + return r.blackSyncer.Sync(ctx, datautil.Batch(ServerBlackToLocalBlack, serverData), localData, nil, false, true) } func (r *Relation) GetDesignatedFriends(ctx context.Context, friendIDs []string) ([]*sdkws.FriendInfo, error) { diff --git a/internal/user/user.go b/internal/user/user.go index e9f1044e7..a35a2c51b 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -69,6 +69,7 @@ func (u *User) initSyncer() { return fmt.Errorf("not support delete user %s", value.UserID) }, func(ctx context.Context, serverUser, localUser *model_struct.LocalUser) error { + u.UserCache.Delete(localUser.UserID) return u.DataBase.UpdateLoginUser(context.Background(), serverUser) }, func(user *model_struct.LocalUser) string { diff --git a/pkg/db/group_member_model.go b/pkg/db/group_member_model.go index 52bf5ea53..0d1fcb006 100644 --- a/pkg/db/group_member_model.go +++ b/pkg/db/group_member_model.go @@ -54,7 +54,7 @@ func (d *DataBase) GetGroupSomeMemberInfo(ctx context.Context, groupID string, u d.mRWMutex.RLock() defer d.mRWMutex.RUnlock() var groupMemberList []*model_struct.LocalGroupMember - err := d.conn.WithContext(ctx).Where("group_id = ? And user_id IN ? ", groupID, userIDList).Find(&groupMemberList).Error + err := d.conn.WithContext(ctx).Where("group_id = ? AND user_id IN ? ", groupID, userIDList).Find(&groupMemberList).Error return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ") } diff --git a/pkg/db/model_struct/data_model_struct.go b/pkg/db/model_struct/data_model_struct.go index 612cab786..7bae3b6d6 100644 --- a/pkg/db/model_struct/data_model_struct.go +++ b/pkg/db/model_struct/data_model_struct.go @@ -399,7 +399,8 @@ func (LocalVersionSync) TableName() string { } type LocalAppSDKVersion struct { - Version string `gorm:"column:version;type:varchar(255);primary_key" json:"version"` + Version string `gorm:"column:version;type:varchar(255);primary_key" json:"version"` + Installed bool `gorm:"column:installed" json:"installed"` // Mark whether it has already been loaded } func (LocalAppSDKVersion) TableName() string { diff --git a/test/long_conn_test.go b/test/long_conn_test.go new file mode 100644 index 000000000..8ad191920 --- /dev/null +++ b/test/long_conn_test.go @@ -0,0 +1,20 @@ +package test + +import ( + "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk" + "testing" + "time" +) + +func Test_SubscribeUsersStatus(t *testing.T) { + time.Sleep(time.Second) + message, err := open_im_sdk.UserForSDK.LongConnMgr().SubscribeUsersStatus(ctx, []string{"5975996883"}) + if err != nil { + t.Error(err) + } + t.Log(message) + ch := make(chan struct{}) + select { + case <-ch: + } +}