share a bunch of the database load code in timeline cache, don't clear timelines on relationship change

This commit is contained in:
kim 2025-04-08 15:19:36 +01:00
commit b04b4f8516
5 changed files with 148 additions and 172 deletions

View file

@ -199,9 +199,6 @@ func (p *Processor) getStatusTimeline(
apiStatuses, lo, hi, err = timelinepkg.LoadStatusTimeline(ctx,
page,
loadPage,
func(ids []string) ([]*gtsmodel.Status, error) {
return p.state.DB.GetStatusesByIDs(ctx, ids)
},
filter,
prepare,
)

View file

@ -683,13 +683,19 @@ func (p *clientAPI) CreateBlock(ctx context.Context, cMsg *messages.FromClientAP
}
if block.Account.IsLocal() {
// Perform timeline invalidation for block origin account.
p.surface.invalidateTimelinesForAccount(ctx, block.AccountID)
// Remove posts by target from origin's timelines.
p.surface.removeRelationshipFromTimelines(ctx,
block.AccountID,
block.TargetAccountID,
)
}
if block.TargetAccount.IsLocal() {
// Perform timeline invalidation for block target account.
p.surface.invalidateTimelinesForAccount(ctx, block.TargetAccountID)
// Remove posts by origin from target's timelines.
p.surface.removeRelationshipFromTimelines(ctx,
block.TargetAccountID,
block.AccountID,
)
}
// TODO: same with notifications?
@ -851,13 +857,19 @@ func (p *clientAPI) UndoFollow(ctx context.Context, cMsg *messages.FromClientAPI
}
if follow.Account.IsLocal() {
// Perform timeline invalidation for block origin account.
p.surface.invalidateTimelinesForAccount(ctx, follow.AccountID)
// Remove posts by target from origin's timelines.
p.surface.removeRelationshipFromTimelines(ctx,
follow.AccountID,
follow.TargetAccountID,
)
}
if follow.TargetAccount.IsLocal() {
// Perform timeline invalidation for block target account.
p.surface.invalidateTimelinesForAccount(ctx, follow.TargetAccountID)
// Remove posts by origin from target's timelines.
p.surface.removeRelationshipFromTimelines(ctx,
follow.TargetAccountID,
follow.AccountID,
)
}
if err := p.federate.UndoFollow(ctx, follow); err != nil {
@ -873,16 +885,6 @@ func (p *clientAPI) UndoBlock(ctx context.Context, cMsg *messages.FromClientAPI)
return gtserror.Newf("%T not parseable as *gtsmodel.Block", cMsg.GTSModel)
}
if block.Account.IsLocal() {
// Perform timeline invalidation for block origin account.
p.surface.invalidateTimelinesForAccount(ctx, block.AccountID)
}
if block.TargetAccount.IsLocal() {
// Perform timeline invalidation for block target account.
p.surface.invalidateTimelinesForAccount(ctx, block.TargetAccountID)
}
if err := p.federate.UndoBlock(ctx, block); err != nil {
log.Errorf(ctx, "error federating block undo: %v", err)
}

View file

@ -715,13 +715,19 @@ func (p *fediAPI) CreateBlock(ctx context.Context, fMsg *messages.FromFediAPI) e
}
if block.Account.IsLocal() {
// Perform timeline invalidation for block origin account.
p.surface.invalidateTimelinesForAccount(ctx, block.AccountID)
// Remove posts by target from origin's timelines.
p.surface.removeRelationshipFromTimelines(ctx,
block.AccountID,
block.TargetAccountID,
)
}
if block.TargetAccount.IsLocal() {
// Perform timeline invalidation for block target account.
p.surface.invalidateTimelinesForAccount(ctx, block.TargetAccountID)
// Remove posts by origin from target's timelines.
p.surface.removeRelationshipFromTimelines(ctx,
block.TargetAccountID,
block.AccountID,
)
}
// Remove any follows that existed between blocker + blockee.
@ -1202,33 +1208,31 @@ func (p *fediAPI) UndoFollow(ctx context.Context, fMsg *messages.FromFediAPI) er
}
if follow.Account.IsLocal() {
// Perform timeline invalidation for block origin account.
p.surface.invalidateTimelinesForAccount(ctx, follow.AccountID)
// Remove posts by target from origin's timelines.
p.surface.removeRelationshipFromTimelines(ctx,
follow.AccountID,
follow.TargetAccountID,
)
}
if follow.TargetAccount.IsLocal() {
// Perform timeline invalidation for block target account.
p.surface.invalidateTimelinesForAccount(ctx, follow.TargetAccountID)
// Remove posts by origin from target's timelines.
p.surface.removeRelationshipFromTimelines(ctx,
follow.TargetAccountID,
follow.AccountID,
)
}
return nil
}
func (p *fediAPI) UndoBlock(ctx context.Context, fMsg *messages.FromFediAPI) error {
block, ok := fMsg.GTSModel.(*gtsmodel.Block)
_, ok := fMsg.GTSModel.(*gtsmodel.Block)
if !ok {
return gtserror.Newf("%T not parseable as *gtsmodel.Block", fMsg.GTSModel)
}
if block.Account.IsLocal() {
// Perform timeline invalidation for block origin account.
p.surface.invalidateTimelinesForAccount(ctx, block.AccountID)
}
if block.TargetAccount.IsLocal() {
// Perform timeline invalidation for block target account.
p.surface.invalidateTimelinesForAccount(ctx, block.TargetAccountID)
}
// TODO: any required changes
return nil
}

View file

@ -826,21 +826,23 @@ func (s *Surface) removeTimelineEntriesByAccount(accountID string) {
s.State.Caches.Timelines.List.RemoveByAccountIDs(accountID)
}
// invalidateTimelinesForAccount invalidates all timeline caches stored for given account ID.
func (s *Surface) invalidateTimelinesForAccount(ctx context.Context, accountID string) {
// There's a lot of visibility changes to caclculate for any
// relationship change, so just clear all account's timelines.
s.State.Caches.Timelines.Home.Clear(accountID)
func (s *Surface) removeRelationshipFromTimelines(ctx context.Context, timelineAccountID string, targetAccountID string) {
// Remove all statuses by target account
// from given account's home timeline.
s.State.Caches.Timelines.Home.
MustGet(timelineAccountID).
RemoveByAccountIDs(targetAccountID)
// Get the IDs of all the lists owned by the given account ID.
listIDs, err := s.State.DB.GetListIDsByAccountID(ctx, accountID)
listIDs, err := s.State.DB.GetListIDsByAccountID(ctx, timelineAccountID)
if err != nil {
log.Errorf(ctx, "error getting lists for account %s: %v", accountID, err)
log.Errorf(ctx, "error getting lists for account %s: %v", timelineAccountID, err)
}
// Clear list timelines of account.
for _, listID := range listIDs {
s.State.Caches.Timelines.List.Clear(listID)
// Remove all statuses by target account
// from given account's list timelines.
s.State.Caches.Timelines.List.MustGet(listID).
RemoveByAccountIDs(targetAccountID)
}
}