fix(wallet)_: collectible manager status nil when unknown network (Anvil)

Replaced map of statuses with sync.Map

Closes #5300
This commit is contained in:
Ivan Belyakov 2024-06-05 18:32:09 +02:00 committed by IvanBelyakoff
parent b1433e6bfa
commit f6a5f1d740
2 changed files with 66 additions and 40 deletions

View File

@ -64,7 +64,7 @@ type Manager struct {
mediaServer *server.MediaServer mediaServer *server.MediaServer
statuses map[string]*connection.Status statuses *sync.Map
statusNotifier *connection.StatusNotifier statusNotifier *connection.StatusNotifier
feed *event.Feed feed *event.Feed
circuitBreakers sync.Map circuitBreakers sync.Map
@ -79,26 +79,7 @@ func NewManager(
feed *event.Feed) *Manager { feed *event.Feed) *Manager {
ownershipDB := NewOwnershipDB(db) ownershipDB := NewOwnershipDB(db)
statuses := initStatuses(ownershipDB)
statuses := make(map[string]*connection.Status)
allChainIDs := walletCommon.AllChainIDs()
for _, chainID := range allChainIDs {
status := connection.NewStatus()
state := status.GetState()
latestUpdateTimestamp, err := ownershipDB.GetLatestOwnershipUpdateTimestamp(chainID)
if err == nil {
state.LastSuccessAt = latestUpdateTimestamp
status.SetState(state)
}
statuses[chainID.String()] = status
}
statusNotifier := connection.NewStatusNotifier(
statuses,
EventCollectiblesConnectionStatusChanged,
feed,
)
return &Manager{ return &Manager{
rpcClient: rpcClient, rpcClient: rpcClient,
@ -112,7 +93,7 @@ func NewManager(
ownershipDB: ownershipDB, ownershipDB: ownershipDB,
mediaServer: mediaServer, mediaServer: mediaServer,
statuses: statuses, statuses: statuses,
statusNotifier: statusNotifier, statusNotifier: createStatusNotifier(statuses, feed),
feed: feed, feed: feed,
} }
} }
@ -775,7 +756,7 @@ func (o *Manager) fetchCommunityAssets(communityID string, communityAssets []*th
return nil return nil
} }
func (o *Manager) fetchCommunityAssetsAsync(ctx context.Context, communityID string, communityAssets []*thirdparty.FullCollectibleData) { func (o *Manager) fetchCommunityAssetsAsync(_ context.Context, communityID string, communityAssets []*thirdparty.FullCollectibleData) {
if len(communityAssets) == 0 { if len(communityAssets) == 0 {
return return
} }
@ -807,7 +788,7 @@ func (o *Manager) fillAnimationMediatype(ctx context.Context, asset *thirdparty.
return nil return nil
} }
func (o *Manager) processCollectionData(ctx context.Context, collections []thirdparty.CollectionData) error { func (o *Manager) processCollectionData(_ context.Context, collections []thirdparty.CollectionData) error {
return o.collectionsDataDB.SetData(collections, true) return o.collectionsDataDB.SetData(collections, true)
} }
@ -895,19 +876,33 @@ func (o *Manager) SetCollectibleTransferID(ownerAddress common.Address, id third
// Reset connection status to trigger notifications // Reset connection status to trigger notifications
// on the next status update // on the next status update
func (o *Manager) ResetConnectionStatus() { func (o *Manager) ResetConnectionStatus() {
for _, status := range o.statuses { o.statuses.Range(func(key, value interface{}) bool {
status.ResetStateValue() value.(*connection.Status).ResetStateValue()
} return true
})
} }
func (o *Manager) checkConnectionStatus(chainID walletCommon.ChainID) { func (o *Manager) checkConnectionStatus(chainID walletCommon.ChainID) {
for _, provider := range o.providers.GetProviderList() { for _, provider := range o.providers.GetProviderList() {
if provider.IsChainSupported(chainID) && provider.IsConnected() { if provider.IsChainSupported(chainID) && provider.IsConnected() {
o.statuses[chainID.String()].SetIsConnected(true) if status, ok := o.statuses.Load(chainID.String()); ok {
status.(*connection.Status).SetIsConnected(true)
}
return return
} }
} }
o.statuses[chainID.String()].SetIsConnected(false)
// If no chain in statuses, add it
statusVal, ok := o.statuses.Load(chainID.String())
status := statusVal.(*connection.Status)
if !ok {
status = connection.NewStatus()
status.SetIsConnected(false)
o.statuses.Store(chainID.String(), status)
o.updateStatusNotifier()
} else {
status.SetIsConnected(false)
}
} }
func (o *Manager) signalUpdatedCollectiblesData(ids []thirdparty.CollectibleUniqueID) { func (o *Manager) signalUpdatedCollectiblesData(ids []thirdparty.CollectibleUniqueID) {
@ -1061,7 +1056,7 @@ func (o *Manager) FetchCollectionSocialsAsync(contractID thirdparty.ContractID)
return nil return nil
} }
func (o *Manager) getOrFetchSocialsForCollection(ctx context.Context, contractID thirdparty.ContractID) (*thirdparty.CollectionSocials, error) { func (o *Manager) getOrFetchSocialsForCollection(_ context.Context, contractID thirdparty.ContractID) (*thirdparty.CollectionSocials, error) {
socials, err := o.collectionsDataDB.GetSocialsForID(contractID) socials, err := o.collectionsDataDB.GetSocialsForID(contractID)
if err != nil { if err != nil {
log.Debug("getOrFetchSocialsForCollection failed for", "chainID", contractID.ChainID, "address", contractID.Address, "err", err) log.Debug("getOrFetchSocialsForCollection failed for", "chainID", contractID.ChainID, "address", contractID.Address, "err", err)
@ -1109,3 +1104,31 @@ func (o *Manager) fetchSocialsForCollection(ctx context.Context, contractID thir
return socials, cmdRes.Error() return socials, cmdRes.Error()
} }
func (o *Manager) updateStatusNotifier() {
o.statusNotifier = createStatusNotifier(o.statuses, o.feed)
}
func initStatuses(ownershipDB *OwnershipDB) *sync.Map {
statuses := &sync.Map{}
for _, chainID := range walletCommon.AllChainIDs() {
status := connection.NewStatus()
state := status.GetState()
latestUpdateTimestamp, err := ownershipDB.GetLatestOwnershipUpdateTimestamp(chainID)
if err == nil {
state.LastSuccessAt = latestUpdateTimestamp
status.SetState(state)
}
statuses.Store(chainID.String(), status)
}
return statuses
}
func createStatusNotifier(statuses *sync.Map, feed *event.Feed) *connection.StatusNotifier {
return connection.NewStatusNotifier(
statuses,
EventCollectiblesConnectionStatusChanged,
feed,
)
}

View File

@ -2,6 +2,7 @@ package connection
import ( import (
"encoding/json" "encoding/json"
"sync"
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -13,21 +14,22 @@ import (
type StatusNotification map[string]State // id -> State type StatusNotification map[string]State // id -> State
type StatusNotifier struct { type StatusNotifier struct {
statuses map[string]*Status // id -> Status statuses *sync.Map // id -> Status
eventType walletevent.EventType eventType walletevent.EventType
feed *event.Feed feed *event.Feed
} }
func NewStatusNotifier(statuses map[string]*Status, eventType walletevent.EventType, feed *event.Feed) *StatusNotifier { func NewStatusNotifier(statuses *sync.Map, eventType walletevent.EventType, feed *event.Feed) *StatusNotifier {
n := StatusNotifier{ n := StatusNotifier{
statuses: statuses, statuses: statuses,
eventType: eventType, eventType: eventType,
feed: feed, feed: feed,
} }
for _, status := range statuses { statuses.Range(func(_, value interface{}) bool {
status.SetStateChangeCb(n.notify) value.(*Status).SetStateChangeCb(n.notify)
} return true
})
return &n return &n
} }
@ -37,13 +39,14 @@ func (n *StatusNotifier) notify(state State) {
// a single event, so we fetch them from the map // a single event, so we fetch them from the map
if n.feed != nil { if n.feed != nil {
statusMap := make(StatusNotification) statusMap := make(StatusNotification)
for id, status := range n.statuses { n.statuses.Range(func(id, value interface{}) bool {
state := status.GetState() state := value.(*Status).GetState()
if state.Value == StateValueUnknown { if state.Value == StateValueUnknown {
continue return true
}
statusMap[id] = state
} }
statusMap[id.(string)] = state
return true
})
encodedMessage, err := json.Marshal(statusMap) encodedMessage, err := json.Marshal(statusMap)
if err != nil { if err != nil {