Skip to content

Commit 1e47f90

Browse files
authored
fix: login user's info maybe empty when app reinstall. (#816)
* fix: login user's info maybe empty when app reinstall. (#814) * fix: login user's info maybe empty when app reinstall. * fix: login user's info maybe empty when app reinstall. * fix: login user's info maybe empty when app reinstall. * fix: add server isEnd determination criteria for message retrieval. Signed-off-by: Gordon <[email protected]> --------- Signed-off-by: Gordon <[email protected]>
1 parent 0bd7376 commit 1e47f90

File tree

6 files changed

+86
-107
lines changed

6 files changed

+86
-107
lines changed

internal/conversation_msg/api.go

+4-8
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,11 @@ func (c *Conversation) GetOneConversation(ctx context.Context, sessionType int32
8080
newConversation.ShowName = g.GroupName
8181
newConversation.FaceURL = g.FaceURL
8282
}
83-
time.Sleep(time.Millisecond * 500)
84-
lc, errTemp := c.db.GetConversation(ctx, conversationID)
85-
if errTemp == nil {
83+
//double check if the conversation exists
84+
lc, err := c.db.GetConversation(ctx, conversationID)
85+
if err == nil {
8686
return lc, nil
8787
}
88-
err := c.db.InsertConversation(ctx, &newConversation)
89-
if err != nil {
90-
return nil, err
91-
}
9288
return &newConversation, nil
9389
}
9490
}
@@ -930,7 +926,7 @@ func (c *Conversation) initBasicInfo(ctx context.Context, message *sdk_struct.Ms
930926
message.IsRead = false
931927
message.Status = constant.MsgStatusSending
932928
message.SendID = c.loginUserID
933-
userInfo, err := c.user.GetUserInfoWithCacheFunc(ctx, c.loginUserID, c.db.GetLoginUser)
929+
userInfo, err := c.user.GetUserInfoWithCache(ctx, c.loginUserID)
934930
if err != nil {
935931
return err
936932
}

internal/conversation_msg/conversation.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (c *Conversation) getAdvancedHistoryMessageList(ctx context.Context, req sd
7676
if err != nil {
7777
return nil, err
7878
}
79-
log.ZDebug(ctx, "pull message", "pull cost time", time.Since(t))
79+
log.ZDebug(ctx, "pull message", "pull cost time", time.Since(t).Milliseconds())
8080
t = time.Now()
8181

8282
messageList = c.LocalChatLog2MsgStruct(list)

internal/conversation_msg/message_check.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -119,19 +119,21 @@ func (c *Conversation) checkEndBlock(ctx context.Context, conversationID string,
119119
_, minSeq, _ := c.getMaxAndMinHaveSeqList(*list)
120120
log.ZDebug(ctx, "validateAndFillEndBlockContinuity", "minSeq", minSeq,
121121
"conversationID", conversationID, "userCanPullMinSeq", userCanPullMinSeq)
122-
if minSeq == userCanPullMinSeq {
122+
// The reason for being less than is that in cases of poor network conditions,
123+
// minSeq may be 0, but in fact, the server's sequence has not yet synchronized to the local.
124+
if minSeq <= userCanPullMinSeq {
123125
messageListCallback.IsEnd = true
124126
} else {
125127
lastMinSeq, _ := c.messagePullForwardEndSeqMap.Load(conversationID)
126128
log.ZDebug(ctx, "validateAndFillEndBlockContinuity", "lastMinSeq", lastMinSeq, "conversationID", conversationID)
127129
// If `minSeq` is zero and `lastMinSeq` is at the minimum server sequence, this batch is fully local
128-
if minSeq == 0 && lastMinSeq == userCanPullMinSeq { // All messages in this batch are local messages,
130+
if minSeq == 0 && lastMinSeq <= userCanPullMinSeq { // All messages in this batch are local messages,
129131
// and the minimum seq of the last batch of valid messages has already reached the minimum pullable seq from the server.
130132
messageListCallback.IsEnd = true
131133
} else {
132134
// The batch includes sequences but has not reached the minimum value,
133-
// This condition indicates local-only messages, with `minSeq > 1` as the only case,
134-
// since `lastMinSeq > 1` is handled in inter-block continuity.
135+
// This condition indicates local-only messages, with `minSeq > userCanPullMinSeq` as the only case,
136+
// since `lastMinSeq > userCanPullMinSeq` is handled in inter-block continuity.
135137
lostSeqList := getLostSeqListWithLimitLength(userCanPullMinSeq, minSeq-1, []int64{})
136138
if len(lostSeqList) > 0 {
137139
isShouldFetchMessage = true

internal/user/api.go

+1-60
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@ package user
22

33
import (
44
"context"
5-
"fmt"
6-
75
"github.com/openimsdk/openim-sdk-core/v3/pkg/common"
86
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
97
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
10-
"github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs"
118
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
129
"github.com/openimsdk/openim-sdk-core/v3/sdk_struct"
1310
"github.com/openimsdk/protocol/sdkws"
@@ -16,18 +13,6 @@ import (
1613
"github.com/openimsdk/tools/utils/datautil"
1714
)
1815

19-
// GetSingleUserFromServer retrieves user information from the server.
20-
func (u *User) GetSingleUserFromServer(ctx context.Context, userID string) (*model_struct.LocalUser, error) {
21-
users, err := u.GetUsersInfoFromServer(ctx, []string{userID})
22-
if err != nil {
23-
return nil, err
24-
}
25-
if len(users) > 0 {
26-
return users[0], nil
27-
}
28-
return nil, sdkerrs.ErrUserIDNotFound.WrapMsg(fmt.Sprintf("getSelfUserInfo failed, userID: %s not exist", userID))
29-
}
30-
3116
// ProcessUserCommandGetAll get user's choice
3217
func (u *User) ProcessUserCommandGetAll(ctx context.Context) ([]*userPb.CommandInfoResp, error) {
3318
localCommands, err := u.DataBase.ProcessUserCommandGetAll(ctx)
@@ -62,25 +47,7 @@ func (u *User) UserOnlineStatusChange(users map[string][]int32) {
6247
}
6348

6449
func (u *User) GetSelfUserInfo(ctx context.Context) (*model_struct.LocalUser, error) {
65-
userInfo, errLocal := u.GetLoginUser(ctx, u.loginUserID)
66-
if errLocal == nil {
67-
return userInfo, nil
68-
}
69-
70-
userInfoFromServer, errServer := u.GetUserInfoFromServer(ctx, []string{u.loginUserID})
71-
if errServer != nil {
72-
return nil, errServer
73-
}
74-
75-
if len(userInfoFromServer) == 0 {
76-
return nil, sdkerrs.ErrUserIDNotFound
77-
}
78-
79-
if err := u.InsertLoginUser(ctx, userInfoFromServer[0]); err != nil {
80-
return nil, err
81-
}
82-
83-
return userInfoFromServer[0], nil
50+
return u.GetUserInfoWithCache(ctx, u.loginUserID)
8451
}
8552

8653
func (u *User) SetSelfInfo(ctx context.Context, userInfo *sdkws.UserInfoWithEx) error {
@@ -123,23 +90,6 @@ func (u *User) ProcessUserCommandUpdate(ctx context.Context, userCommand *userPb
12390
return u.SyncAllCommand(ctx)
12491
}
12592

126-
// GetUserInfoFromServer retrieves user information from the server.
127-
func (u *User) GetUserInfoFromServer(ctx context.Context, userIDs []string) ([]*model_struct.LocalUser, error) {
128-
var err error
129-
130-
serverUsersInfo, err := u.getUsersInfo(ctx, userIDs)
131-
if err != nil {
132-
return nil, err
133-
}
134-
135-
if len(serverUsersInfo) == 0 {
136-
log.ZError(ctx, "serverUsersInfo is empty", err, "userIDs", userIDs)
137-
return nil, err
138-
}
139-
140-
return datautil.Batch(ServerUserToLocalUser, serverUsersInfo), nil
141-
}
142-
14393
func (u *User) GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdk_struct.PublicUser, error) {
14494
usersInfo, err := u.GetUsersInfoWithCache(ctx, userIDs)
14595
if err != nil {
@@ -178,12 +128,3 @@ func (u *User) GetUsersInfo(ctx context.Context, userIDs []string) ([]*sdk_struc
178128
}
179129
return res, nil
180130
}
181-
182-
// GetUsersInfoFromServer retrieves user information from the server.
183-
func (u *User) GetUsersInfoFromServer(ctx context.Context, userIDs []string) ([]*model_struct.LocalUser, error) {
184-
users, err := u.getUsersInfo(ctx, userIDs)
185-
if err != nil {
186-
return nil, sdkerrs.WrapMsg(err, "GetUsersInfoFromServer failed")
187-
}
188-
return datautil.Batch(ServerUserToLocalUser, users), nil
189-
}

internal/user/user.go

+30-12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ package user
1717
import (
1818
"context"
1919
"fmt"
20+
"github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs"
21+
"github.com/openimsdk/tools/log"
2022

2123
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
2224
"github.com/openimsdk/openim-sdk-core/v3/pkg/cache"
@@ -37,7 +39,8 @@ func NewUser(dataBase db_interface.DataBase, loginUserID string, conversationCh
3739
user.UserCache = cache.NewManager[string, *model_struct.LocalUser](
3840
func(value *model_struct.LocalUser) string { return value.UserID },
3941
nil,
40-
user.GetUserInfoFromServer,
42+
user.GetLoginUser,
43+
user.GetUsersInfoFromServer,
4144
)
4245
return user
4346
}
@@ -136,27 +139,42 @@ func (u *User) initSyncer() {
136139
}
137140

138141
func (u *User) GetUserInfoWithCache(ctx context.Context, cacheKey string) (*model_struct.LocalUser, error) {
139-
return u.UserCache.FetchGet(ctx, cacheKey)
142+
return u.UserCache.Fetch(ctx, cacheKey)
140143
}
141144

142-
func (u *User) GetUserInfoWithCacheFunc(ctx context.Context, cacheKey string, fetchFunc func(ctx context.Context, key string) (*model_struct.LocalUser, error)) (*model_struct.LocalUser, error) {
143-
if userInfo, ok := u.UserCache.Load(cacheKey); ok {
144-
return userInfo, nil
145+
func (u *User) GetUsersInfoWithCache(ctx context.Context, cacheKeys []string) ([]*model_struct.LocalUser, error) {
146+
m, err := u.UserCache.BatchFetch(ctx, cacheKeys)
147+
if err != nil {
148+
return nil, err
145149
}
150+
return datautil.Values(m), nil
151+
}
146152

147-
fetchedData, err := fetchFunc(ctx, cacheKey)
153+
// GetSingleUserFromServer retrieves user information from the server.
154+
func (u *User) GetSingleUserFromServer(ctx context.Context, userID string) (*model_struct.LocalUser, error) {
155+
users, err := u.getUsersInfo(ctx, []string{userID})
148156
if err != nil {
149157
return nil, err
150158
}
151-
152-
u.UserCache.Store(cacheKey, fetchedData)
153-
return fetchedData, nil
159+
if len(users) > 0 {
160+
return ServerUserToLocalUser(users[0]), nil
161+
}
162+
return nil, sdkerrs.ErrUserIDNotFound.WrapMsg(fmt.Sprintf("getSelfUserInfo failed, userID: %s not exist", userID))
154163
}
155164

156-
func (u *User) GetUsersInfoWithCache(ctx context.Context, cacheKeys []string) ([]*model_struct.LocalUser, error) {
157-
m, err := u.UserCache.MultiFetchGet(ctx, cacheKeys)
165+
// GetUsersInfoFromServer retrieves user information from the server.
166+
func (u *User) GetUsersInfoFromServer(ctx context.Context, userIDs []string) ([]*model_struct.LocalUser, error) {
167+
var err error
168+
169+
serverUsersInfo, err := u.getUsersInfo(ctx, userIDs)
158170
if err != nil {
159171
return nil, err
160172
}
161-
return datautil.Values(m), nil
173+
174+
if len(serverUsersInfo) == 0 {
175+
log.ZError(ctx, "serverUsersInfo is empty", err, "userIDs", userIDs)
176+
return nil, err
177+
}
178+
179+
return datautil.Batch(ServerUserToLocalUser, serverUsersInfo), nil
162180
}

pkg/cache/manager.go

+44-22
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,34 @@ package cache
22

33
import (
44
"context"
5+
"github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs"
56
"github.com/openimsdk/tools/utils/datautil"
67
)
78

89
func NewManager[K comparable, V any](
910
getKeyFunc func(value V) K,
10-
dbFunc func(ctx context.Context, keys []K) ([]V, error),
11+
batchDBFunc func(ctx context.Context, keys []K) ([]V, error),
12+
singleDBFunc func(ctx context.Context, keys K) (V, error),
1113
queryFunc func(ctx context.Context, keys []K) ([]V, error),
1214
) *Manager[K, V] {
1315
return &Manager[K, V]{
14-
Cache: Cache[K, V]{},
15-
getKeyFunc: getKeyFunc,
16-
dbFunc: dbFunc,
17-
queryFunc: queryFunc,
16+
Cache: Cache[K, V]{},
17+
getKeyFunc: getKeyFunc,
18+
batchDBFunc: batchDBFunc,
19+
singleDBFunc: singleDBFunc,
20+
queryFunc: queryFunc,
1821
}
1922
}
2023

2124
type Manager[K comparable, V any] struct {
2225
Cache[K, V]
23-
getKeyFunc func(value V) K
24-
dbFunc func(ctx context.Context, keys []K) ([]V, error)
25-
queryFunc func(ctx context.Context, keys []K) ([]V, error)
26+
getKeyFunc func(value V) K
27+
batchDBFunc func(ctx context.Context, keys []K) ([]V, error)
28+
singleDBFunc func(ctx context.Context, keys K) (V, error)
29+
queryFunc func(ctx context.Context, keys []K) ([]V, error)
2630
}
2731

28-
func (m *Manager[K, V]) MultiFetchGet(ctx context.Context, keys []K) (map[K]V, error) {
32+
func (m *Manager[K, V]) BatchFetch(ctx context.Context, keys []K) (map[K]V, error) {
2933
var (
3034
res = make(map[K]V)
3135
queryKeys []K
@@ -39,7 +43,7 @@ func (m *Manager[K, V]) MultiFetchGet(ctx context.Context, keys []K) (map[K]V, e
3943
}
4044
}
4145

42-
writeData, err := m.Fetch(ctx, queryKeys)
46+
writeData, err := m.batchFetch(ctx, queryKeys)
4347
if err != nil {
4448
return nil, err
4549
}
@@ -52,27 +56,22 @@ func (m *Manager[K, V]) MultiFetchGet(ctx context.Context, keys []K) (map[K]V, e
5256
return res, nil
5357
}
5458

55-
func (m *Manager[K, V]) FetchGet(ctx context.Context, key K) (V, error) {
59+
func (m *Manager[K, V]) Fetch(ctx context.Context, key K) (V, error) {
5660
var nilData V
5761

5862
if data, ok := m.Load(key); ok {
5963
return data, nil
6064
}
6165

62-
fetchedData, err := m.Fetch(ctx, []K{key})
66+
fetchedData, err := m.fetch(ctx, key)
6367
if err != nil {
6468
return nilData, err
6569
}
66-
if len(fetchedData) > 0 {
67-
m.Store(key, fetchedData[0])
68-
return fetchedData[0], nil
69-
}
70-
71-
// todo: return error or nilData?
72-
return nilData, nil
70+
m.Store(key, fetchedData)
71+
return fetchedData, nil
7372
}
7473

75-
func (m *Manager[K, V]) Fetch(ctx context.Context, keys []K) ([]V, error) {
74+
func (m *Manager[K, V]) batchFetch(ctx context.Context, keys []K) ([]V, error) {
7675
if len(keys) == 0 {
7776
return nil, nil
7877
}
@@ -81,8 +80,8 @@ func (m *Manager[K, V]) Fetch(ctx context.Context, keys []K) ([]V, error) {
8180
writeData []V
8281
)
8382

84-
if m.dbFunc != nil {
85-
dbData, err := m.dbFunc(ctx, queryKeys)
83+
if m.batchDBFunc != nil {
84+
dbData, err := m.batchDBFunc(ctx, queryKeys)
8685
if err != nil {
8786
return nil, err
8887
}
@@ -99,8 +98,31 @@ func (m *Manager[K, V]) Fetch(ctx context.Context, keys []K) ([]V, error) {
9998
if err != nil {
10099
return nil, err
101100
}
101+
if len(queryData) == 0 {
102+
return writeData, sdkerrs.ErrUserIDNotFound.WrapMsg("fetch data not found", "keys", keys)
103+
}
102104
writeData = append(writeData, queryData...)
103105
}
104106

105107
return writeData, nil
106108
}
109+
func (m *Manager[K, V]) fetch(ctx context.Context, key K) (V, error) {
110+
var writeData V
111+
if m.singleDBFunc != nil {
112+
dbData, err := m.singleDBFunc(ctx, key)
113+
if err == nil {
114+
return dbData, nil
115+
}
116+
}
117+
if m.queryFunc != nil {
118+
queryData, err := m.queryFunc(ctx, []K{key})
119+
if err != nil {
120+
return writeData, err
121+
}
122+
if len(queryData) > 0 {
123+
return queryData[0], nil
124+
}
125+
return writeData, sdkerrs.ErrUserIDNotFound.WrapMsg("fetch data not found", "key", key)
126+
}
127+
return writeData, nil
128+
}

0 commit comments

Comments
 (0)