[bugfix] media.Processor{}.GetFile() returning 404s on first call, correctly loading on 2nd (#3129)

* refactor file handling a tiny bit

* whoops

* make processing media / emoji defers a bit clear to see that it's the "on finished processing" path

* some wording

* add some debug logging

* add mutex locks for processing remote media

* try removing freshness check

* fix derefMedia not being allocated

* fix log format string

* handle case of empty file paths (i.e. not stored)

* remove media / emoji once finished processing from dereferencer maps

* whoops, fix the cached / force checks

* move url parsing outside of 'process___Safely()' funcs to prevalidate url

* use emoji.ShortcodeDomain()

* update RefreshEmoji() to also match RefreshMedia() changes

---------

Co-authored-by: tobi <tobi.smethurst@protonmail.com>
This commit is contained in:
kim 2024-07-22 18:45:48 +01:00 committed by GitHub
commit 31294f7c78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 385 additions and 293 deletions

View file

@ -22,7 +22,6 @@ import (
errorsv2 "codeberg.org/gruf/go-errors/v2"
"codeberg.org/gruf/go-runners"
"github.com/superseriousbusiness/gotosocial/internal/gtscontext"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/log"
@ -77,42 +76,34 @@ func (p *ProcessingEmoji) load(ctx context.Context) (
defer func() {
// This is only done when ctx NOT cancelled.
done = (err == nil || !errorsv2.IsV2(err,
if done = (err == nil || !errorsv2.IsV2(err,
context.Canceled,
context.DeadlineExceeded,
))
)); done {
// Processing finished,
// whether error or not!
if !done {
return
// Anything from here, we
// need to ensure happens
// (i.e. no ctx canceled).
ctx = context.WithoutCancel(ctx)
// On error, clean
// downloaded files.
if err != nil {
p.cleanup(ctx)
}
// Update with latest details, whatever happened.
e := p.mgr.state.DB.UpdateEmoji(ctx, p.emoji)
if e != nil {
log.Errorf(ctx, "error updating emoji in db: %v", e)
}
// Store values.
p.done = true
p.err = err
}
// Anything from here, we
// need to ensure happens
// (i.e. no ctx canceled).
ctx = gtscontext.WithValues(
context.Background(),
ctx, // values
)
// On error, clean
// downloaded files.
if err != nil {
p.cleanup(ctx)
}
if !done {
return
}
// Update with latest details, whatever happened.
e := p.mgr.state.DB.UpdateEmoji(ctx, p.emoji)
if e != nil {
log.Errorf(ctx, "error updating emoji in db: %v", e)
}
// Store final values.
p.done = true
p.err = err
}()
// Attempt to store media and calculate
@ -122,7 +113,10 @@ func (p *ProcessingEmoji) load(ctx context.Context) (
err = p.store(ctx)
return err
})
emoji = p.emoji
// Return a copy of emoji.
emoji = new(gtsmodel.Emoji)
*emoji = *p.emoji
return
}
@ -265,11 +259,11 @@ func (p *ProcessingEmoji) store(ctx context.Context) error {
// cleanup will remove any traces of processing emoji from storage,
// and perform any other necessary cleanup steps after failure.
func (p *ProcessingEmoji) cleanup(ctx context.Context) {
var err error
log.Debugf(ctx, "running cleanup of emoji %s", p.emoji.ID)
if p.emoji.ImagePath != "" {
// Ensure emoji file at path is deleted from storage.
err = p.mgr.state.Storage.Delete(ctx, p.emoji.ImagePath)
err := p.mgr.state.Storage.Delete(ctx, p.emoji.ImagePath)
if err != nil && !storage.IsNotFound(err) {
log.Errorf(ctx, "error deleting %s: %v", p.emoji.ImagePath, err)
}
@ -277,7 +271,7 @@ func (p *ProcessingEmoji) cleanup(ctx context.Context) {
if p.emoji.ImageStaticPath != "" {
// Ensure emoji static file at path is deleted from storage.
err = p.mgr.state.Storage.Delete(ctx, p.emoji.ImageStaticPath)
err := p.mgr.state.Storage.Delete(ctx, p.emoji.ImageStaticPath)
if err != nil && !storage.IsNotFound(err) {
log.Errorf(ctx, "error deleting %s: %v", p.emoji.ImageStaticPath, err)
}