From 1aa1363e63f4e0421ec83bed07135e2ed7f9884b Mon Sep 17 00:00:00 2001 From: Alex Sahin Date: Mon, 1 Jul 2019 11:44:09 +0100 Subject: [PATCH] [MM-16568] Migrate "User.SearchInChannel" to Sync by default (#11417) * implemented migration to sync * updated user.go to use explicit async approach --- app/user.go | 18 ++++++++++++------ store/sqlstore/user_store.go | 18 ++++++++++-------- store/store.go | 2 +- store/storetest/mocks/UserStore.go | 19 ++++++++++++++----- store/storetest/user_store.go | 6 +++--- 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/app/user.go b/app/user.go index 45cb840bdd..8ea501f22b 100644 --- a/app/user.go +++ b/app/user.go @@ -1674,12 +1674,10 @@ func (a *App) SearchUsers(props *model.UserSearch, options *model.UserSearchOpti func (a *App) SearchUsersInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { term = strings.TrimSpace(term) - result := <-a.Srv.Store.User().SearchInChannel(channelId, term, options) - if result.Err != nil { - return nil, result.Err + users, err := a.Srv.Store.User().SearchInChannel(channelId, term, options) + if err != nil { + return nil, err } - users := result.Data.([]*model.User) - for _, user := range users { a.SanitizeProfile(user, options.IsAdmin) } @@ -1847,13 +1845,21 @@ func (a *App) AutocompleteUsersInChannel(teamId string, channelId string, term s if !a.IsESAutocompletionEnabled() || err != nil { autocomplete = &model.UserAutocompleteInChannel{} - uchan := a.Srv.Store.User().SearchInChannel(channelId, term, options) + + uchan := make(chan store.StoreResult, 1) + go func() { + users, err := a.Srv.Store.User().SearchInChannel(channelId, term, options) + uchan <- store.StoreResult{Data: users, Err: err} + close(uchan) + }() + nuchan := a.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, options) result := <-uchan if result.Err != nil { return nil, result.Err } + users := result.Data.([]*model.User) for _, user := range users { diff --git a/store/sqlstore/user_store.go b/store/sqlstore/user_store.go index 9c45f958ce..bdacdf50b3 100644 --- a/store/sqlstore/user_store.go +++ b/store/sqlstore/user_store.go @@ -1303,15 +1303,17 @@ func (us SqlUserStore) SearchNotInChannel(teamId string, channelId string, term }) } -func (us SqlUserStore) SearchInChannel(channelId string, term string, options *model.UserSearchOptions) store.StoreChannel { - return store.Do(func(result *store.StoreResult) { - query := us.usersQuery. - Join("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId). - OrderBy("Username ASC"). - Limit(uint64(options.Limit)) +func (us SqlUserStore) SearchInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { + query := us.usersQuery. + Join("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId). + OrderBy("Username ASC"). + Limit(uint64(options.Limit)) - *result = us.performSearch(query, term, options) - }) + result := us.performSearch(query, term, options) + if result.Err != nil { + return nil, result.Err + } + return result.Data.([]*model.User), nil } var escapeLikeSearchChar = []string{ diff --git a/store/store.go b/store/store.go index 7bcdd6a7b8..4c00e4f89b 100644 --- a/store/store.go +++ b/store/store.go @@ -290,7 +290,7 @@ type UserStore interface { GetNewUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) Search(teamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) SearchNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) - SearchInChannel(channelId string, term string, options *model.UserSearchOptions) StoreChannel + SearchInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) SearchNotInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) StoreChannel SearchWithoutTeam(term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) AnalyticsGetInactiveUsersCount() (int64, *model.AppError) diff --git a/store/storetest/mocks/UserStore.go b/store/storetest/mocks/UserStore.go index 55e695463f..f32d1f4ae1 100644 --- a/store/storetest/mocks/UserStore.go +++ b/store/storetest/mocks/UserStore.go @@ -824,19 +824,28 @@ func (_m *UserStore) Search(teamId string, term string, options *model.UserSearc } // SearchInChannel provides a mock function with given fields: channelId, term, options -func (_m *UserStore) SearchInChannel(channelId string, term string, options *model.UserSearchOptions) store.StoreChannel { +func (_m *UserStore) SearchInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { ret := _m.Called(channelId, term, options) - var r0 store.StoreChannel - if rf, ok := ret.Get(0).(func(string, string, *model.UserSearchOptions) store.StoreChannel); ok { + var r0 []*model.User + if rf, ok := ret.Get(0).(func(string, string, *model.UserSearchOptions) []*model.User); ok { r0 = rf(channelId, term, options) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(store.StoreChannel) + r0 = ret.Get(0).([]*model.User) } } - return r0 + var r1 *model.AppError + if rf, ok := ret.Get(1).(func(string, string, *model.UserSearchOptions) *model.AppError); ok { + r1 = rf(channelId, term, options) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 } // SearchNotInChannel provides a mock function with given fields: teamId, channelId, term, options diff --git a/store/storetest/user_store.go b/store/storetest/user_store.go index 65c3134442..f9bf32b1c1 100644 --- a/store/storetest/user_store.go +++ b/store/storetest/user_store.go @@ -2825,13 +2825,13 @@ func testUserStoreSearchInChannel(t *testing.T, ss store.Store) { for _, testCase := range testCases { t.Run(testCase.Description, func(t *testing.T) { - result := <-ss.User().SearchInChannel( + users, err := ss.User().SearchInChannel( testCase.ChannelId, testCase.Term, testCase.Options, ) - require.Nil(t, result.Err) - assertUsers(t, testCase.Expected, result.Data.([]*model.User)) + require.Nil(t, err) + assertUsers(t, testCase.Expected, users) }) } }