From 5e2897e35cd2bea889fa37a2a857f4dcc076dafc Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Sun, 11 Jun 2023 11:18:44 +0200 Subject: [bugfix] Invalidate timeline entries for status when stats change (#1879) --- internal/processing/fromcommon.go | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'internal/processing/fromcommon.go') diff --git a/internal/processing/fromcommon.go b/internal/processing/fromcommon.go index fcb539087..5889da4f7 100644 --- a/internal/processing/fromcommon.go +++ b/internal/processing/fromcommon.go @@ -29,6 +29,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/id" + "github.com/superseriousbusiness/gotosocial/internal/log" "github.com/superseriousbusiness/gotosocial/internal/stream" "github.com/superseriousbusiness/gotosocial/internal/timeline" ) @@ -419,7 +420,7 @@ func (p *Processor) wipeStatus(ctx context.Context, statusToDelete *gtsmodel.Sta // delete all boosts for this status + remove them from timelines if boosts, err := p.state.DB.GetStatusReblogs(ctx, statusToDelete); err == nil { for _, b := range boosts { - if err := p.deleteStatusFromTimelines(ctx, b); err != nil { + if err := p.deleteStatusFromTimelines(ctx, b.ID); err != nil { return err } if err := p.state.DB.DeleteStatusByID(ctx, b.ID); err != nil { @@ -429,7 +430,7 @@ func (p *Processor) wipeStatus(ctx context.Context, statusToDelete *gtsmodel.Sta } // delete this status from any and all timelines - if err := p.deleteStatusFromTimelines(ctx, statusToDelete); err != nil { + if err := p.deleteStatusFromTimelines(ctx, statusToDelete.ID); err != nil { return err } @@ -439,16 +440,36 @@ func (p *Processor) wipeStatus(ctx context.Context, statusToDelete *gtsmodel.Sta // deleteStatusFromTimelines completely removes the given status from all timelines. // It will also stream deletion of the status to all open streams. -func (p *Processor) deleteStatusFromTimelines(ctx context.Context, status *gtsmodel.Status) error { - if err := p.state.Timelines.Home.WipeItemFromAllTimelines(ctx, status.ID); err != nil { +func (p *Processor) deleteStatusFromTimelines(ctx context.Context, statusID string) error { + if err := p.state.Timelines.Home.WipeItemFromAllTimelines(ctx, statusID); err != nil { return err } - if err := p.state.Timelines.List.WipeItemFromAllTimelines(ctx, status.ID); err != nil { + if err := p.state.Timelines.List.WipeItemFromAllTimelines(ctx, statusID); err != nil { return err } - return p.stream.Delete(status.ID) + return p.stream.Delete(statusID) +} + +// invalidateStatusFromTimelines does cache invalidation on the given status by +// unpreparing it from all timelines, forcing it to be prepared again (with updated +// stats, boost counts, etc) next time it's fetched by the timeline owner. This goes +// both for the status itself, and for any boosts of the status. +func (p *Processor) invalidateStatusFromTimelines(ctx context.Context, statusID string) { + if err := p.state.Timelines.Home.UnprepareItemFromAllTimelines(ctx, statusID); err != nil { + log. + WithContext(ctx). + WithField("statusID", statusID). + Errorf("error unpreparing status from home timelines: %v", err) + } + + if err := p.state.Timelines.List.UnprepareItemFromAllTimelines(ctx, statusID); err != nil { + log. + WithContext(ctx). + WithField("statusID", statusID). + Errorf("error unpreparing status from list timelines: %v", err) + } } /* -- cgit v1.2.3