mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[bugfix] Invalidate timeline entries for status when stats change (#1879)
This commit is contained in:
@@ -53,7 +53,12 @@ func (p *Processor) BookmarkCreate(ctx context.Context, requestingAccount *gtsmo
|
||||
}
|
||||
|
||||
if err := p.state.DB.PutStatusBookmark(ctx, gtsBookmark); err != nil {
|
||||
err = fmt.Errorf("BookmarkCreate: error putting bookmark in database: %w", err)
|
||||
err = gtserror.Newf("error putting bookmark in database: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if err := p.invalidateStatus(ctx, requestingAccount.ID, targetStatusID); err != nil {
|
||||
err = gtserror.Newf("error invalidating status from timelines: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
@@ -74,7 +79,12 @@ func (p *Processor) BookmarkRemove(ctx context.Context, requestingAccount *gtsmo
|
||||
|
||||
// We have a bookmark to remove.
|
||||
if err := p.state.DB.DeleteStatusBookmark(ctx, existingBookmarkID); err != nil {
|
||||
err = fmt.Errorf("BookmarkRemove: error removing status bookmark: %w", err)
|
||||
err = gtserror.Newf("error removing status bookmark: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if err := p.invalidateStatus(ctx, requestingAccount.ID, targetStatusID); err != nil {
|
||||
err = gtserror.Newf("error invalidating status from timelines: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
|
@@ -21,15 +21,17 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"codeberg.org/gruf/go-kv"
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/log"
|
||||
)
|
||||
|
||||
func (p *Processor) apiStatus(ctx context.Context, targetStatus *gtsmodel.Status, requestingAccount *gtsmodel.Account) (*apimodel.Status, gtserror.WithCode) {
|
||||
apiStatus, err := p.tc.StatusToAPIStatus(ctx, targetStatus, requestingAccount)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error converting status %s to frontend representation: %w", targetStatus.ID, err)
|
||||
err = gtserror.Newf("error converting status %s to frontend representation: %w", targetStatus.ID, err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
@@ -66,3 +68,36 @@ func (p *Processor) getVisibleStatus(ctx context.Context, requestingAccount *gts
|
||||
|
||||
return targetStatus, nil
|
||||
}
|
||||
|
||||
// invalidateStatus is a shortcut function for invalidating the prepared/cached
|
||||
// representation one status in the home timeline and all list timelines of the
|
||||
// given accountID. It should only be called in cases where a status update
|
||||
// does *not* need to be passed into the processor via the worker queue, since
|
||||
// such invalidation will, in that case, be handled by the processor instead.
|
||||
func (p *Processor) invalidateStatus(ctx context.Context, accountID string, statusID string) error {
|
||||
// Get lists first + bail if this fails.
|
||||
lists, err := p.state.DB.GetListsForAccountID(ctx, accountID)
|
||||
if err != nil {
|
||||
return gtserror.Newf("db error getting lists for account %s: %w", accountID, err)
|
||||
}
|
||||
|
||||
l := log.WithContext(ctx).WithFields(kv.Fields{
|
||||
{"accountID", accountID},
|
||||
{"statusID", statusID},
|
||||
}...)
|
||||
|
||||
// Unprepare item from home + list timelines, just log
|
||||
// if something goes wrong since this is not a showstopper.
|
||||
|
||||
if err := p.state.Timelines.Home.UnprepareItem(ctx, accountID, statusID); err != nil {
|
||||
l.Errorf("error unpreparing item from home timeline: %v", err)
|
||||
}
|
||||
|
||||
for _, list := range lists {
|
||||
if err := p.state.Timelines.List.UnprepareItem(ctx, list.ID, statusID); err != nil {
|
||||
l.Errorf("error unpreparing item from list timeline %s: %v", list.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -95,7 +95,13 @@ func (p *Processor) PinCreate(ctx context.Context, requestingAccount *gtsmodel.A
|
||||
|
||||
targetStatus.PinnedAt = time.Now()
|
||||
if err := p.state.DB.UpdateStatus(ctx, targetStatus, "pinned_at"); err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error pinning status: %w", err))
|
||||
err = gtserror.Newf("db error pinning status: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if err := p.invalidateStatus(ctx, requestingAccount.ID, targetStatusID); err != nil {
|
||||
err = gtserror.Newf("error invalidating status from timelines: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
return p.apiStatus(ctx, targetStatus, requestingAccount)
|
||||
@@ -118,11 +124,19 @@ func (p *Processor) PinRemove(ctx context.Context, requestingAccount *gtsmodel.A
|
||||
return nil, errWithCode
|
||||
}
|
||||
|
||||
if !targetStatus.PinnedAt.IsZero() {
|
||||
targetStatus.PinnedAt = time.Time{}
|
||||
if err := p.state.DB.UpdateStatus(ctx, targetStatus, "pinned_at"); err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error unpinning status: %w", err))
|
||||
}
|
||||
if targetStatus.PinnedAt.IsZero() {
|
||||
return p.apiStatus(ctx, targetStatus, requestingAccount)
|
||||
}
|
||||
|
||||
targetStatus.PinnedAt = time.Time{}
|
||||
if err := p.state.DB.UpdateStatus(ctx, targetStatus, "pinned_at"); err != nil {
|
||||
err = gtserror.Newf("db error unpinning status: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if err := p.invalidateStatus(ctx, requestingAccount.ID, targetStatusID); err != nil {
|
||||
err = gtserror.Newf("error invalidating status from timelines: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
return p.apiStatus(ctx, targetStatus, requestingAccount)
|
||||
|
Reference in New Issue
Block a user