diff options
Diffstat (limited to 'internal/federation/dereferencing/account.go')
-rw-r--r-- | internal/federation/dereferencing/account.go | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/internal/federation/dereferencing/account.go b/internal/federation/dereferencing/account.go index 21900d47b..0e7bc1cc9 100644 --- a/internal/federation/dereferencing/account.go +++ b/internal/federation/dereferencing/account.go @@ -26,7 +26,6 @@ import ( "io" "net/url" "strings" - "sync" "time" "github.com/miekg/dns" @@ -478,9 +477,7 @@ func (d *deref) fetchRemoteAccountMedia(ctx context.Context, targetAccount *gtsm if alreadyProcessing, ok := d.dereferencingAvatars[targetAccount.ID]; ok { // we're already on it, no worries processingMedia = alreadyProcessing - } - - if processingMedia == nil { + } else { // we're not already processing it so start now avatarIRI, err := url.Parse(targetAccount.AvatarRemoteURL) if err != nil { @@ -492,6 +489,7 @@ func (d *deref) fetchRemoteAccountMedia(ctx context.Context, targetAccount *gtsm var err error t, err = d.transportController.NewTransportForUsername(ctx, requestingUsername) if err != nil { + d.dereferencingAvatarsLock.Unlock() return false, fmt.Errorf("fetchRemoteAccountMedia: error getting transport for user: %s", err) } } @@ -516,16 +514,27 @@ func (d *deref) fetchRemoteAccountMedia(ctx context.Context, targetAccount *gtsm } d.dereferencingAvatarsLock.Unlock() // UNLOCK HERE + load := func(innerCtx context.Context) error { + _, err := processingMedia.LoadAttachment(innerCtx) + return err + } + + cleanup := func() { + d.dereferencingAvatarsLock.Lock() + delete(d.dereferencingAvatars, targetAccount.ID) + d.dereferencingAvatarsLock.Unlock() + } + // block until loaded if required... if blocking { - if err := lockAndLoad(ctx, d.dereferencingAvatarsLock, processingMedia, d.dereferencingAvatars, targetAccount.ID); err != nil { + if err := loadAndCleanup(ctx, load, cleanup); err != nil { return changed, err } } else { // ...otherwise do it async go func() { dlCtx, done := context.WithDeadline(context.Background(), time.Now().Add(1*time.Minute)) - if err := lockAndLoad(dlCtx, d.dereferencingAvatarsLock, processingMedia, d.dereferencingAvatars, targetAccount.ID); err != nil { + if err := loadAndCleanup(dlCtx, load, cleanup); err != nil { log.Errorf("fetchRemoteAccountMedia: error during async lock and load of avatar: %s", err) } done() @@ -544,9 +553,7 @@ func (d *deref) fetchRemoteAccountMedia(ctx context.Context, targetAccount *gtsm if alreadyProcessing, ok := d.dereferencingHeaders[targetAccount.ID]; ok { // we're already on it, no worries processingMedia = alreadyProcessing - } - - if processingMedia == nil { + } else { // we're not already processing it so start now headerIRI, err := url.Parse(targetAccount.HeaderRemoteURL) if err != nil { @@ -558,6 +565,7 @@ func (d *deref) fetchRemoteAccountMedia(ctx context.Context, targetAccount *gtsm var err error t, err = d.transportController.NewTransportForUsername(ctx, requestingUsername) if err != nil { + d.dereferencingAvatarsLock.Unlock() return false, fmt.Errorf("fetchRemoteAccountMedia: error getting transport for user: %s", err) } } @@ -582,16 +590,27 @@ func (d *deref) fetchRemoteAccountMedia(ctx context.Context, targetAccount *gtsm } d.dereferencingHeadersLock.Unlock() // UNLOCK HERE + load := func(innerCtx context.Context) error { + _, err := processingMedia.LoadAttachment(innerCtx) + return err + } + + cleanup := func() { + d.dereferencingHeadersLock.Lock() + delete(d.dereferencingHeaders, targetAccount.ID) + d.dereferencingHeadersLock.Unlock() + } + // block until loaded if required... if blocking { - if err := lockAndLoad(ctx, d.dereferencingHeadersLock, processingMedia, d.dereferencingHeaders, targetAccount.ID); err != nil { + if err := loadAndCleanup(ctx, load, cleanup); err != nil { return changed, err } } else { // ...otherwise do it async go func() { dlCtx, done := context.WithDeadline(context.Background(), time.Now().Add(1*time.Minute)) - if err := lockAndLoad(dlCtx, d.dereferencingHeadersLock, processingMedia, d.dereferencingHeaders, targetAccount.ID); err != nil { + if err := loadAndCleanup(dlCtx, load, cleanup); err != nil { log.Errorf("fetchRemoteAccountMedia: error during async lock and load of header: %s", err) } done() @@ -615,7 +634,7 @@ func (d *deref) fetchRemoteAccountEmojis(ctx context.Context, targetAccount *gts // If we only have IDs, fetch the emojis from the db. We know they're in // there or else they wouldn't have IDs. if len(maybeEmojiIDs) > len(maybeEmojis) { - maybeEmojis = []*gtsmodel.Emoji{} + maybeEmojis = make([]*gtsmodel.Emoji, 0, len(maybeEmojiIDs)) for _, emojiID := range maybeEmojiIDs { maybeEmoji, err := d.db.GetEmojiByID(ctx, emojiID) if err != nil { @@ -716,16 +735,3 @@ func (d *deref) fetchRemoteAccountEmojis(ctx context.Context, targetAccount *gts return changed, nil } - -func lockAndLoad(ctx context.Context, lock *sync.Mutex, processing *media.ProcessingMedia, processingMap map[string]*media.ProcessingMedia, accountID string) error { - // whatever happens, remove the in-process media from the map - defer func() { - lock.Lock() - delete(processingMap, accountID) - lock.Unlock() - }() - - // try and load it - _, err := processing.LoadAttachment(ctx) - return err -} |