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
statuses map[string]*connection.Status
statuses *sync.Map
statusNotifier *connection.StatusNotifier
feed *event.Feed
circuitBreakers sync.Map
@ -79,26 +79,7 @@ func NewManager(
feed *event.Feed) *Manager {
ownershipDB := NewOwnershipDB(db)
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,
)
statuses := initStatuses(ownershipDB)
return &Manager{
rpcClient: rpcClient,
@ -112,7 +93,7 @@ func NewManager(
ownershipDB: ownershipDB,
mediaServer: mediaServer,
statuses: statuses,
statusNotifier: statusNotifier,
statusNotifier: createStatusNotifier(statuses, feed),
feed: feed,
}
}
@ -775,7 +756,7 @@ func (o *Manager) fetchCommunityAssets(communityID string, communityAssets []*th
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 {
return
}
@ -807,7 +788,7 @@ func (o *Manager) fillAnimationMediatype(ctx context.Context, asset *thirdparty.
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)
}
@ -895,19 +876,33 @@ func (o *Manager) SetCollectibleTransferID(ownerAddress common.Address, id third
// Reset connection status to trigger notifications
// on the next status update
func (o *Manager) ResetConnectionStatus() {
for _, status := range o.statuses {
status.ResetStateValue()
}
o.statuses.Range(func(key, value interface{}) bool {
value.(*connection.Status).ResetStateValue()
return true
})
}
func (o *Manager) checkConnectionStatus(chainID walletCommon.ChainID) {
for _, provider := range o.providers.GetProviderList() {
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
}
}
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) {
@ -1061,7 +1056,7 @@ func (o *Manager) FetchCollectionSocialsAsync(contractID thirdparty.ContractID)
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)
if err != nil {
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()
}
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 (
"encoding/json"
"sync"
"time"
"github.com/ethereum/go-ethereum/common"
@ -13,21 +14,22 @@ import (
type StatusNotification map[string]State // id -> State
type StatusNotifier struct {
statuses map[string]*Status // id -> Status
statuses *sync.Map // id -> Status
eventType walletevent.EventType
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{
statuses: statuses,
eventType: eventType,
feed: feed,
}
for _, status := range statuses {
status.SetStateChangeCb(n.notify)
}
statuses.Range(func(_, value interface{}) bool {
value.(*Status).SetStateChangeCb(n.notify)
return true
})
return &n
}
@ -37,13 +39,14 @@ func (n *StatusNotifier) notify(state State) {
// a single event, so we fetch them from the map
if n.feed != nil {
statusMap := make(StatusNotification)
for id, status := range n.statuses {
state := status.GetState()
n.statuses.Range(func(id, value interface{}) bool {
state := value.(*Status).GetState()
if state.Value == StateValueUnknown {
continue
return true
}
statusMap[id] = state
}
statusMap[id.(string)] = state
return true
})
encodedMessage, err := json.Marshal(statusMap)
if err != nil {