fix_: improve `fetchCommunityAssets` performance

fixes: #5038
This commit is contained in:
Patryk Osmaczko 2024-04-10 11:21:41 +02:00 committed by osmaczko
parent e6fee1a84e
commit 759e5e5c7b
5 changed files with 45 additions and 46 deletions

View File

@ -52,6 +52,7 @@ import (
"github.com/status-im/status-go/services/ext/mailservers" "github.com/status-im/status-go/services/ext/mailservers"
mailserversDB "github.com/status-im/status-go/services/mailservers" mailserversDB "github.com/status-im/status-go/services/mailservers"
"github.com/status-im/status-go/services/wallet" "github.com/status-im/status-go/services/wallet"
"github.com/status-im/status-go/services/wallet/collectibles"
w_common "github.com/status-im/status-go/services/wallet/common" w_common "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/thirdparty" "github.com/status-im/status-go/services/wallet/thirdparty"
"github.com/status-im/status-go/wakuv2" "github.com/status-im/status-go/wakuv2"
@ -533,7 +534,30 @@ func (s *Service) GetCommunityID(tokenURI string) string {
return "" return ""
} }
func (s *Service) FillCollectibleMetadata(collectible *thirdparty.FullCollectibleData) error { func (s *Service) FillCollectiblesMetadata(communityID string, cs []*thirdparty.FullCollectibleData) (bool, error) {
if s.messenger == nil {
return false, fmt.Errorf("messenger not ready")
}
community, err := s.fetchCommunityInfoForCollectibles(communityID, collectibles.IDsFromAssets(cs))
if err != nil {
return false, err
}
if community == nil {
return false, nil
}
for _, collectible := range cs {
err := s.FillCollectibleMetadata(community, collectible)
if err != nil {
return true, err
}
}
return true, nil
}
func (s *Service) FillCollectibleMetadata(community *communities.Community, collectible *thirdparty.FullCollectibleData) error {
if s.messenger == nil { if s.messenger == nil {
return fmt.Errorf("messenger not ready") return fmt.Errorf("messenger not ready")
} }
@ -549,14 +573,6 @@ func (s *Service) FillCollectibleMetadata(collectible *thirdparty.FullCollectibl
return fmt.Errorf("invalid communityID") return fmt.Errorf("invalid communityID")
} }
community, err := s.messenger.FindCommunityInfoFromDB(communityID)
if err != nil {
if err == communities.ErrOrgNotFound {
return nil
}
return err
}
tokenMetadata, err := s.fetchCommunityCollectibleMetadata(community, id.ContractID) tokenMetadata, err := s.fetchCommunityCollectibleMetadata(community, id.ContractID)
if err != nil { if err != nil {
@ -632,7 +648,7 @@ func communityToInfo(community *communities.Community) *thirdparty.CommunityInfo
} }
} }
func (s *Service) fetchCommunityFromStoreNodes(communityID string) (*thirdparty.CommunityInfo, error) { func (s *Service) fetchCommunityFromStoreNodes(communityID string) (*communities.Community, error) {
community, err := s.messenger.FetchCommunity(&protocol.FetchCommunityRequest{ community, err := s.messenger.FetchCommunity(&protocol.FetchCommunityRequest{
CommunityKey: communityID, CommunityKey: communityID,
TryDatabase: false, TryDatabase: false,
@ -641,7 +657,7 @@ func (s *Service) fetchCommunityFromStoreNodes(communityID string) (*thirdparty.
if err != nil { if err != nil {
return nil, err return nil, err
} }
return communityToInfo(community), nil return community, nil
} }
// Fetch latest community from store nodes. // Fetch latest community from store nodes.
@ -657,18 +673,17 @@ func (s *Service) FetchCommunityInfo(communityID string) (*thirdparty.CommunityI
// Fetch latest version from store nodes // Fetch latest version from store nodes
if community == nil || !community.IsControlNode() { if community == nil || !community.IsControlNode() {
return s.fetchCommunityFromStoreNodes(communityID) community, err = s.fetchCommunityFromStoreNodes(communityID)
if err != nil {
return nil, err
}
} }
return communityToInfo(community), nil return communityToInfo(community), nil
} }
// Fetch latest community from store nodes only if any collectibles data is missing. // Fetch latest community from store nodes only if any collectibles data is missing.
func (s *Service) FetchCommunityInfoForCollectibles(communityID string, ids []thirdparty.CollectibleUniqueID) (*thirdparty.CommunityInfo, error) { func (s *Service) fetchCommunityInfoForCollectibles(communityID string, ids []thirdparty.CollectibleUniqueID) (*communities.Community, error) {
if s.messenger == nil {
return nil, fmt.Errorf("messenger not ready")
}
community, err := s.messenger.FindCommunityInfoFromDB(communityID) community, err := s.messenger.FindCommunityInfoFromDB(communityID)
if err != nil && err != communities.ErrOrgNotFound { if err != nil && err != communities.ErrOrgNotFound {
return nil, err return nil, err
@ -679,7 +694,7 @@ func (s *Service) FetchCommunityInfoForCollectibles(communityID string, ids []th
} }
if community.IsControlNode() { if community.IsControlNode() {
return communityToInfo(community), nil return community, nil
} }
contractIDs := func() map[string]thirdparty.ContractID { contractIDs := func() map[string]thirdparty.ContractID {
@ -706,7 +721,7 @@ func (s *Service) FetchCommunityInfoForCollectibles(communityID string, ids []th
return s.fetchCommunityFromStoreNodes(communityID) return s.fetchCommunityFromStoreNodes(communityID)
} }
return communityToInfo(community), nil return community, nil
} }
func (s *Service) fetchCommunityToken(communityID string, contractID thirdparty.ContractID) (*token.CommunityToken, error) { func (s *Service) fetchCommunityToken(communityID string, contractID thirdparty.ContractID) (*token.CommunityToken, error) {

View File

@ -728,25 +728,16 @@ func (o *Manager) fillCommunityID(asset *thirdparty.FullCollectibleData) error {
} }
func (o *Manager) fetchCommunityAssets(communityID string, communityAssets []*thirdparty.FullCollectibleData) error { func (o *Manager) fetchCommunityAssets(communityID string, communityAssets []*thirdparty.FullCollectibleData) error {
communityInfo, err := o.communityManager.FetchCommunityInfoForCollectibles(communityID, idsFromAssets(communityAssets)) communityFound, err := o.communityManager.FillCollectiblesMetadata(communityID, communityAssets)
if err != nil {
log.Error("FillCollectiblesMetadata failed", "communityID", communityID, "err", err)
} else if !communityFound {
log.Warn("fetchCommunityAssets community not found", "communityID", communityID)
}
// If the community is found, we update the DB. // If the community is found, we update the DB.
// If the community is not found, we only insert new entries to the DB (don't replace what is already there). // If the community is not found, we only insert new entries to the DB (don't replace what is already there).
allowUpdate := false allowUpdate := communityFound
if err != nil {
log.Error("fetchCommunityInfo failed", "communityID", communityID, "err", err)
} else if communityInfo == nil {
log.Warn("fetchCommunityAssets community not found", "communityID", communityID)
} else {
for _, communityAsset := range communityAssets {
err := o.communityManager.FillCollectibleMetadata(communityAsset)
if err != nil {
log.Error("FillCollectibleMetadata failed", "communityID", communityID, "err", err)
return err
}
}
allowUpdate = true
}
collectiblesData := make([]thirdparty.CollectibleData, 0, len(communityAssets)) collectiblesData := make([]thirdparty.CollectibleData, 0, len(communityAssets))
collectionsData := make([]thirdparty.CollectionData, 0, len(communityAssets)) collectionsData := make([]thirdparty.CollectionData, 0, len(communityAssets))

View File

@ -205,7 +205,7 @@ func communityInfoToData(communityID string, community *thirdparty.CommunityInfo
return ret return ret
} }
func idsFromAssets(assets []*thirdparty.FullCollectibleData) []thirdparty.CollectibleUniqueID { func IDsFromAssets(assets []*thirdparty.FullCollectibleData) []thirdparty.CollectibleUniqueID {
result := make([]thirdparty.CollectibleUniqueID, len(assets)) result := make([]thirdparty.CollectibleUniqueID, len(assets))
for i, asset := range assets { for i, asset := range assets {
result[i] = asset.CollectibleData.ID result[i] = asset.CollectibleData.ID

View File

@ -58,8 +58,8 @@ func (cm *Manager) GetCommunityID(tokenURI string) string {
return cm.communityInfoProvider.GetCommunityID(tokenURI) return cm.communityInfoProvider.GetCommunityID(tokenURI)
} }
func (cm *Manager) FillCollectibleMetadata(c *thirdparty.FullCollectibleData) error { func (cm *Manager) FillCollectiblesMetadata(communityID string, cs []*thirdparty.FullCollectibleData) (bool, error) {
return cm.communityInfoProvider.FillCollectibleMetadata(c) return cm.communityInfoProvider.FillCollectiblesMetadata(communityID, cs)
} }
func (cm *Manager) setCommunityInfo(id string, c *thirdparty.CommunityInfo) (err error) { func (cm *Manager) setCommunityInfo(id string, c *thirdparty.CommunityInfo) (err error) {
@ -85,12 +85,6 @@ func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.Community
}) })
} }
func (cm *Manager) FetchCommunityInfoForCollectibles(communityID string, ids []thirdparty.CollectibleUniqueID) (*thirdparty.CommunityInfo, error) {
return cm.fetchCommunityInfo(communityID, func() (*thirdparty.CommunityInfo, error) {
return cm.communityInfoProvider.FetchCommunityInfoForCollectibles(communityID, ids)
})
}
func (cm *Manager) FetchCommunityMetadataAsync(communityID string) { func (cm *Manager) FetchCommunityMetadataAsync(communityID string) {
go func() { go func() {
communityInfo, err := cm.FetchCommunityMetadata(communityID) communityInfo, err := cm.FetchCommunityMetadata(communityID)

View File

@ -13,6 +13,5 @@ type CommunityInfoProvider interface {
// Collectible-related methods // Collectible-related methods
GetCommunityID(tokenURI string) string GetCommunityID(tokenURI string) string
FillCollectibleMetadata(collectible *FullCollectibleData) error FillCollectiblesMetadata(communityID string, cs []*FullCollectibleData) (bool, error)
FetchCommunityInfoForCollectibles(communityID string, ids []CollectibleUniqueID) (*CommunityInfo, error)
} }