refactor(server_media)_: pass a func to get the images instead of using the cache

The community cache that the image server was using was not intended to be used for that. It can be invalidated at any moment. Also, it did not contain changes made by admins (admin events).
Using this new approach, we pass functions from the community manager to the media server so that it can have access to the correct community description.
This commit is contained in:
Jonathan Rainville 2024-11-26 14:15:27 -05:00
parent ee7f4d249c
commit d197857034
4 changed files with 59 additions and 36 deletions

View File

@ -477,6 +477,23 @@ func NewManager(
manager.forceMembersReevaluation = make(map[string]chan struct{}, 10)
}
if mediaServer != nil {
mediaServer.SetCommunityImageReader(func(communityID string) (map[string]*protobuf.IdentityImage, error) {
community, err := manager.GetByIDString(communityID)
if err != nil {
return nil, err
}
return community.Images(), nil
})
mediaServer.SetCommunityTokensReader(func(communityID string) ([]*protobuf.CommunityTokenMetadata, error) {
community, err := manager.GetByIDString(communityID)
if err != nil {
return nil, err
}
return community.CommunityTokensMetadata(), nil
})
}
return manager, nil
}

View File

@ -14,9 +14,6 @@ import (
"strconv"
"time"
"github.com/golang/protobuf/proto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/protobuf"
"go.uber.org/zap"
@ -1000,7 +997,7 @@ func handleCommunityTokenImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc
}
}
func handleCommunityDescriptionImagesPath(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
func handleCommunityDescriptionImagesPath(db *sql.DB, getCommunityImages func(communityID string) (map[string]*protobuf.IdentityImage, error), logger *zap.Logger) http.HandlerFunc {
if db == nil {
return handleRequestDBMissing(logger)
}
@ -1019,17 +1016,13 @@ func handleCommunityDescriptionImagesPath(db *sql.DB, logger *zap.Logger) http.H
name = params["name"][0]
}
err, communityDescription := getCommunityDescription(db, communityID, logger)
communityImages, err := getCommunityImages(communityID)
if err != nil {
return
}
if communityDescription.Identity == nil {
logger.Error("no identity in community description", zap.String("community id", communityID))
return
}
var imagePayload []byte
for t, i := range communityDescription.Identity.Images {
for t, i := range communityImages {
if t == name {
imagePayload = i.Payload
}
@ -1053,7 +1046,7 @@ func handleCommunityDescriptionImagesPath(db *sql.DB, logger *zap.Logger) http.H
}
}
func handleCommunityDescriptionTokenImagesPath(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
func handleCommunityDescriptionTokenImagesPath(db *sql.DB, getCommunityTokens func(communityID string) ([]*protobuf.CommunityTokenMetadata, error), logger *zap.Logger) http.HandlerFunc {
if db == nil {
return handleRequestDBMissing(logger)
}
@ -1073,13 +1066,13 @@ func handleCommunityDescriptionTokenImagesPath(db *sql.DB, logger *zap.Logger) h
}
symbol := params["symbol"][0]
err, communityDescription := getCommunityDescription(db, communityID, logger)
communityTokens, err := getCommunityTokens(communityID)
if err != nil {
return
}
var foundToken *protobuf.CommunityTokenMetadata
for _, m := range communityDescription.CommunityTokensMetadata {
for _, m := range communityTokens {
if m.GetSymbol() == symbol {
foundToken = m
}
@ -1108,23 +1101,6 @@ func handleCommunityDescriptionTokenImagesPath(db *sql.DB, logger *zap.Logger) h
}
}
// getCommunityDescription returns the latest community description from the cache.
// NOTE: you should ensure preprocessDescription is called before this function.
func getCommunityDescription(db *sql.DB, communityID string, logger *zap.Logger) (error, *protobuf.CommunityDescription) {
var descriptionBytes []byte
err := db.QueryRow(`SELECT description FROM encrypted_community_description_cache WHERE community_id = ? ORDER BY clock DESC LIMIT 1`, types.Hex2Bytes(communityID)).Scan(&descriptionBytes)
if err != nil {
logger.Error("failed to find community description", zap.String("community id", communityID), zap.Error(err))
return err, nil
}
communityDescription := new(protobuf.CommunityDescription)
err = proto.Unmarshal(descriptionBytes, communityDescription)
if err != nil {
logger.Error("failed to unmarshal community description", zap.String("community id", communityID), zap.Error(err))
}
return err, communityDescription
}
func handleWalletCommunityImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
if db == nil {
return handleRequestDBMissing(logger)

View File

@ -3,6 +3,7 @@ package server
import (
"crypto/tls"
"database/sql"
"errors"
"net/url"
"strconv"
@ -10,6 +11,7 @@ import (
"github.com/status-im/status-go/logutils"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/services/wallet/thirdparty"
"github.com/status-im/status-go/signal"
)
@ -25,10 +27,12 @@ func WithMediaServerDisableTLS(disableTLS bool) MediaServerOption {
type MediaServer struct {
Server
db *sql.DB
downloader *ipfs.Downloader
multiaccountsDB *multiaccounts.Database
walletDB *sql.DB
db *sql.DB
downloader *ipfs.Downloader
multiaccountsDB *multiaccounts.Database
walletDB *sql.DB
getCommunityImagesReader func(communityID string) (map[string]*protobuf.IdentityImage, error)
getCommunityTokenReader func(communityID string) ([]*protobuf.CommunityTokenMetadata, error)
// disableTLS controls whether the media server uses HTTP instead of HTTPS.
// Set to true to avoid TLS certificate issues with react-native-fast-image
@ -89,8 +93,8 @@ func NewMediaServer(db *sql.DB, downloader *ipfs.Downloader, multiaccountsDB *mu
LinkPreviewFaviconPath: handleLinkPreviewFavicon(s.db, s.logger),
StatusLinkPreviewThumbnailPath: handleStatusLinkPreviewThumbnail(s.db, s.logger),
communityTokenImagesPath: handleCommunityTokenImages(s.db, s.logger),
communityDescriptionImagesPath: handleCommunityDescriptionImagesPath(s.db, s.logger),
communityDescriptionTokenImagesPath: handleCommunityDescriptionTokenImagesPath(s.db, s.logger),
communityDescriptionImagesPath: handleCommunityDescriptionImagesPath(s.db, s.getCommunityImage, s.logger),
communityDescriptionTokenImagesPath: handleCommunityDescriptionTokenImagesPath(s.db, s.getCommunityTokens, s.logger),
walletCommunityImagesPath: handleWalletCommunityImages(s.walletDB, s.logger),
walletCollectionImagesPath: handleWalletCollectionImages(s.walletDB, s.logger),
walletCollectibleImagesPath: handleWalletCollectibleImages(s.walletDB, s.logger),
@ -106,6 +110,28 @@ func (s *MediaServer) MakeBaseURL() *url.URL {
}
}
func (s *MediaServer) SetCommunityImageReader(getFunc func(communityID string) (map[string]*protobuf.IdentityImage, error)) {
s.getCommunityImagesReader = getFunc
}
func (s *MediaServer) getCommunityImage(communityID string) (map[string]*protobuf.IdentityImage, error) {
if s.getCommunityImagesReader == nil {
return nil, errors.New("community image reader not set")
}
return s.getCommunityImagesReader(communityID)
}
func (s *MediaServer) SetCommunityTokensReader(getFunc func(communityID string) ([]*protobuf.CommunityTokenMetadata, error)) {
s.getCommunityTokenReader = getFunc
}
func (s *MediaServer) getCommunityTokens(communityID string) ([]*protobuf.CommunityTokenMetadata, error) {
if s.getCommunityTokenReader == nil {
return nil, errors.New("community token reader not set")
}
return s.getCommunityTokenReader(communityID)
}
func (s *MediaServer) MakeImageServerURL() string {
u := s.MakeBaseURL()
u.Path = basePath + "/"

View File

@ -1,6 +1,10 @@
package server
import "github.com/status-im/status-go/protocol/protobuf"
type MediaServerInterface interface {
MakeCommunityDescriptionTokenImageURL(communityID, symbol string) string
MakeCommunityImageURL(communityID, name string) string
SetCommunityImageReader(func(communityID string) (map[string]*protobuf.IdentityImage, error))
SetCommunityTokensReader(func(communityID string) ([]*protobuf.CommunityTokenMetadata, error))
}