[bugfix] concurrent map writes in dereferencer media processing maps (#2964)

* removes the avatar / header deref maps as we now have per-uri status / account locks, adds retries on data-races, adds separate emoji map mutex

* work with a copy of account / status for each retry loop

* revert to old data race behaviour, it gets too complicated otherwise

---------

Co-authored-by: tobi <tobi.smethurst@protonmail.com>
This commit is contained in:
kim 2024-06-06 08:50:14 +00:00 committed by GitHub
commit 3b7faac604
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 78 additions and 113 deletions

View file

@ -85,11 +85,22 @@ type Dereferencer struct {
mediaManager *media.Manager
visibility *visibility.Filter
// all protected by State{}.FedLocks.
derefAvatars map[string]*media.ProcessingMedia
derefHeaders map[string]*media.ProcessingMedia
derefEmojis map[string]*media.ProcessingEmoji
// in-progress dereferencing emoji. we already perform
// locks per-status and per-account so we don't need
// processing maps for other media which won't often
// end up being repeated. worst case we run into an
// db.ErrAlreadyExists error which then gets handled
// appropriately by enrich{Account,Status}Safely().
derefEmojis map[string]*media.ProcessingEmoji
derefEmojisMu sync.Mutex
// handshakes marks current in-progress handshakes
// occurring, useful to prevent a deadlock between
// gotosocial instances attempting to dereference
// accounts for the first time. when a handshake is
// currently ongoing we know not to block waiting
// on certain data and instead return an in-progress
// form of the data as we currently see it.
handshakes map[string][]*url.URL
handshakesMu sync.Mutex
}
@ -108,8 +119,6 @@ func NewDereferencer(
transportController: transportController,
mediaManager: mediaManager,
visibility: visFilter,
derefAvatars: make(map[string]*media.ProcessingMedia),
derefHeaders: make(map[string]*media.ProcessingMedia),
derefEmojis: make(map[string]*media.ProcessingEmoji),
handshakes: make(map[string][]*url.URL),
}