diff options
| author | 2025-10-08 14:13:40 +0200 | |
|---|---|---|
| committer | 2025-11-17 14:02:55 +0100 | |
| commit | d1812357b3882409ac5b6cb987881547c8370619 (patch) | |
| tree | 56759af05ccfb0f39f70e77d79eeb8719a4b8e2e /internal/federation/dereferencing | |
| parent | [chore] Better handling of Gone accounts during `PostInbox` (return 202 Accep... (diff) | |
| download | gotosocial-d1812357b3882409ac5b6cb987881547c8370619.tar.xz | |
[performance] handle emoji refreshes asynchronously when fetched as part of account|status dereferences (#4486)
# Description
Updates our dereferencer emoji handling to work asynchronously when going through the route of account or status dereferencing.
closes https://codeberg.org/superseriousbusiness/gotosocial/issues/4485
## Checklist
- [x] I/we have read the [GoToSocial contribution guidelines](https://codeberg.org/superseriousbusiness/gotosocial/src/branch/main/CONTRIBUTING.md).
- [x] I/we have discussed the proposed changes already, either in an issue on the repository, or in the Matrix chat.
- [x] I/we have not leveraged AI to create the proposed changes.
- [x] I/we have performed a self-review of added code.
- [x] I/we have written code that is legible and maintainable by others.
- [ ] I/we have commented the added code, particularly in hard-to-understand areas.
- [ ] I/we have made any necessary changes to documentation.
- [ ] I/we have added tests that cover new code.
- [ ] I/we have run tests and they pass locally with the changes.
- [x] I/we have run `go fmt ./...` and `golangci-lint run`.
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4486
Co-authored-by: kim <grufwub@gmail.com>
Co-committed-by: kim <grufwub@gmail.com>
Diffstat (limited to 'internal/federation/dereferencing')
| -rw-r--r-- | internal/federation/dereferencing/emoji.go | 48 | ||||
| -rw-r--r-- | internal/federation/dereferencing/emoji_test.go | 1 |
2 files changed, 33 insertions, 16 deletions
diff --git a/internal/federation/dereferencing/emoji.go b/internal/federation/dereferencing/emoji.go index fbe2e4d98..b8ecfa6e1 100644 --- a/internal/federation/dereferencing/emoji.go +++ b/internal/federation/dereferencing/emoji.go @@ -51,6 +51,7 @@ func (d *Dereferencer) GetEmoji( remoteURL string, info media.AdditionalEmojiInfo, refresh bool, + async bool, ) ( *gtsmodel.Emoji, error, @@ -66,7 +67,7 @@ func (d *Dereferencer) GetEmoji( if emoji != nil { // This was an existing emoji, pass to refresh func. - return d.RefreshEmoji(ctx, emoji, info, refresh) + return d.RefreshEmoji(ctx, emoji, info, refresh, async) } if domain == "" { @@ -112,6 +113,7 @@ func (d *Dereferencer) GetEmoji( info, ) }, + async, ) } @@ -130,6 +132,7 @@ func (d *Dereferencer) RefreshEmoji( emoji *gtsmodel.Emoji, info media.AdditionalEmojiInfo, force bool, + async bool, ) ( *gtsmodel.Emoji, error, @@ -162,7 +165,7 @@ func (d *Dereferencer) RefreshEmoji( // We still want to make sure // the emoji is cached. Simply // check whether emoji is cached. - return d.RecacheEmoji(ctx, emoji) + return d.RecacheEmoji(ctx, emoji, async) } // Can't refresh local. @@ -207,6 +210,7 @@ func (d *Dereferencer) RefreshEmoji( info, ) }, + async, ) } @@ -222,6 +226,7 @@ func (d *Dereferencer) RefreshEmoji( func (d *Dereferencer) RecacheEmoji( ctx context.Context, emoji *gtsmodel.Emoji, + async bool, ) ( *gtsmodel.Emoji, error, @@ -272,23 +277,24 @@ func (d *Dereferencer) RecacheEmoji( data, ) }, + async, ) - } // processingEmojiSafely provides concurrency-safe processing of // an emoji with given shortcode+domain. if a copy of the emoji is // not already being processed, the given 'process' callback will -// be used to generate new *media.ProcessingEmoji{} instance. +// be used to generate new *media.ProcessingEmoji{} instance. async +// determines whether to load it immediately, or in the background. func (d *Dereferencer) processEmojiSafely( ctx context.Context, shortcodeDomain string, process func() (*media.ProcessingEmoji, error), + async bool, ) ( emoji *gtsmodel.Emoji, err error, ) { - // Acquire map lock. d.derefEmojisMu.Lock() @@ -309,25 +315,34 @@ func (d *Dereferencer) processEmojiSafely( // Add processing emoji media to hash map. d.derefEmojis[shortcodeDomain] = processing + } + // Unlock map. + unlock() + + if async { + emoji = processing.LoadAsync(func() { + // Remove on finish. + d.derefEmojisMu.Lock() + delete(d.derefEmojis, shortcodeDomain) + d.derefEmojisMu.Unlock() + }) + } else { defer func() { // Remove on finish. d.derefEmojisMu.Lock() delete(d.derefEmojis, shortcodeDomain) d.derefEmojisMu.Unlock() }() - } - - // Unlock map. - unlock() - // Perform emoji load operation. - emoji, err = processing.Load(ctx) - if err != nil { - err = gtserror.Newf("error loading emoji %s: %w", shortcodeDomain, err) + // Perform emoji load operation. + emoji, err = processing.Load(ctx) + if err != nil { + err = gtserror.Newf("error loading emoji %s: %w", shortcodeDomain, err) - // TODO: in time we should return checkable flags by gtserror.Is___() - // which can determine if loading error should allow remaining placeholder. + // TODO: in time we should return checkable flags by gtserror.Is___() + // which can determine if loading error should allow remaining placeholder. + } } return @@ -364,7 +379,7 @@ func (d *Dereferencer) fetchEmojis( URI: &placeholder.URI, ImageRemoteURL: &placeholder.ImageRemoteURL, ImageStaticRemoteURL: &placeholder.ImageStaticRemoteURL, - }, force) + }, force, true) if err != nil { log.Errorf(ctx, "error refreshing emoji: %v", err) @@ -396,6 +411,7 @@ func (d *Dereferencer) fetchEmojis( ImageStaticRemoteURL: &placeholder.ImageStaticRemoteURL, }, false, + true, ) if err != nil { if emoji == nil { diff --git a/internal/federation/dereferencing/emoji_test.go b/internal/federation/dereferencing/emoji_test.go index c8c905781..5a4a1f601 100644 --- a/internal/federation/dereferencing/emoji_test.go +++ b/internal/federation/dereferencing/emoji_test.go @@ -54,6 +54,7 @@ func (suite *EmojiTestSuite) TestDereferenceEmojiBlocking() { VisibleInPicker: &emojiVisibleInPicker, }, false, + false, ) suite.NoError(err) suite.NotNil(emoji) |
