Skip to content

Commit 38363d0

Browse files
jrainvillealexjba
authored andcommitted
fix(communities): fix saving communities is slow because of token fetch
Part of status-im/status-app#20954 I found that saving a big community, like the Status app, for the first time is very slow, averaging 35 seconds. Turns out the reason is because of the community tokens. The community description handling called the token data fetching in the same thread and in a blocking way. Meaning that nothing was returned until the tokens were fetched. It also means that if the token fetching failed, the whole community saving and signaling would fail. I moved the token handling in another thread, so that it doesn't slow the main operation. Then, once the fetching and saving is done, we signal again the new community data (cherry picked from commit 2bee8b6) (cherry picked from commit 17f1f2f) (cherry picked from commit 758adcec55c3e4c5c2f4ac571d406a099ad50b26)
1 parent 72d3706 commit 38363d0

2 files changed

Lines changed: 53 additions & 11 deletions

File tree

protocol/communities/manager.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,10 +2172,6 @@ func (m *Manager) handleCommunityDescriptionMessageCommon(community *Community,
21722172
m.incrementCommunityImageVersion(community.IDString())
21732173
}
21742174

2175-
if err = m.handleCommunityTokensMetadata(community); err != nil {
2176-
return nil, err
2177-
}
2178-
21792175
hasCommunityArchiveInfo, err := m.persistence.HasCommunityArchiveInfo(community.ID())
21802176
if err != nil {
21812177
return nil, err
@@ -2261,6 +2257,10 @@ func (m *Manager) handleCommunityDescriptionMessageCommon(community *Community,
22612257
return nil, err
22622258
}
22632259

2260+
if len(community.CommunityTokensMetadata()) > 0 {
2261+
m.handleCommunityTokensMetadataAsync(community.IDString())
2262+
}
2263+
22642264
// We mark our requests as completed, though maybe we should mark
22652265
// any request for any user that has been added as completed
22662266
if err := m.markRequestToJoinAsAccepted(&m.identity.PublicKey, community); err != nil {
@@ -4471,6 +4471,31 @@ func (m *Manager) handleCommunityTokensMetadata(community *Community) error {
44714471
return nil
44724472
}
44734473

4474+
func (m *Manager) handleCommunityTokensMetadataAsync(communityID string) {
4475+
go func() {
4476+
defer utils.LogOnPanic()
4477+
4478+
select {
4479+
case <-m.quit:
4480+
return
4481+
default:
4482+
}
4483+
4484+
community, err := m.GetByIDString(communityID)
4485+
if err != nil {
4486+
return
4487+
}
4488+
4489+
err = m.handleCommunityTokensMetadata(community)
4490+
if err != nil {
4491+
return
4492+
}
4493+
4494+
m.publish(&Subscription{Community: community})
4495+
4496+
}()
4497+
}
4498+
44744499
func (m *Manager) HandleCommunityGrant(community *Community, grant []byte, clock uint64) (uint64, error) {
44754500
_, oldClock, err := m.GetCommunityGrant(community.IDString())
44764501
if err != nil {

protocol/communities_events_utils_test.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,16 +1866,33 @@ func testAddAndSyncTokenFromControlNode(base CommunityEventsTestsInterface, comm
18661866
waitOnMessengerResponse(s, checkTokenAdded, base.GetMember())
18671867
waitOnMessengerResponse(s, checkTokenAdded, base.GetEventSender())
18681868

1869-
// check CommunityToken was added to the DB
1870-
syncTokens, err := base.GetEventSender().communitiesManager.GetAllCommunityTokens()
1869+
// Token metadata arrives via messenger response first; DB persistence can complete shortly after.
1870+
err = testutils.RetryWithBackOff(func() error {
1871+
syncTokens, err := base.GetEventSender().communitiesManager.GetAllCommunityTokens()
1872+
if err != nil {
1873+
return err
1874+
}
1875+
if len(syncTokens) != 1 {
1876+
return errors.New("event sender tokens should be 1")
1877+
}
1878+
if syncTokens[0].PrivilegesLevel != privilegesLvl {
1879+
return errors.New("event sender token privileges level does not match")
1880+
}
1881+
return nil
1882+
})
18711883
s.Require().NoError(err)
1872-
s.Require().Len(syncTokens, 1)
1873-
s.Require().Equal(syncTokens[0].PrivilegesLevel, privilegesLvl)
18741884

1875-
// check CommunityToken was added to the DB
1876-
syncTokens, err = base.GetMember().communitiesManager.GetAllCommunityTokens()
1885+
err = testutils.RetryWithBackOff(func() error {
1886+
syncTokens, err := base.GetMember().communitiesManager.GetAllCommunityTokens()
1887+
if err != nil {
1888+
return err
1889+
}
1890+
if len(syncTokens) != 1 {
1891+
return errors.New("member tokens should be 1")
1892+
}
1893+
return nil
1894+
})
18771895
s.Require().NoError(err)
1878-
s.Require().Len(syncTokens, 1)
18791896
}
18801897

18811898
func testAddAndSyncOwnerTokenFromControlNode(base CommunityEventsTestsInterface, community *communities.Community,

0 commit comments

Comments
 (0)