mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[performance] add caching of status fave, boost of, in reply to ID lists (#2060)
This commit is contained in:
@@ -330,7 +330,7 @@ statusLoop:
|
||||
})
|
||||
|
||||
// Look for any boosts of this status in DB.
|
||||
boosts, err := p.state.DB.GetStatusReblogs(ctx, status)
|
||||
boosts, err := p.state.DB.GetStatusBoosts(ctx, status.ID)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
return gtserror.Newf("error fetching status reblogs for %s: %w", status.ID, err)
|
||||
}
|
||||
|
@@ -380,6 +380,8 @@ func (p *Processor) notify(
|
||||
// wipeStatus contains common logic used to totally delete a status
|
||||
// + all its attachments, notifications, boosts, and timeline entries.
|
||||
func (p *Processor) wipeStatus(ctx context.Context, statusToDelete *gtsmodel.Status, deleteAttachments bool) error {
|
||||
var errs gtserror.MultiError
|
||||
|
||||
// either delete all attachments for this status, or simply
|
||||
// unattach all attachments for this status, so they'll be
|
||||
// cleaned later by a separate process; reason to unattach rather
|
||||
@@ -389,14 +391,14 @@ func (p *Processor) wipeStatus(ctx context.Context, statusToDelete *gtsmodel.Sta
|
||||
// todo: p.state.DB.DeleteAttachmentsForStatus
|
||||
for _, a := range statusToDelete.AttachmentIDs {
|
||||
if err := p.media.Delete(ctx, a); err != nil {
|
||||
return err
|
||||
errs.Appendf("error deleting media: %w", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// todo: p.state.DB.UnattachAttachmentsForStatus
|
||||
for _, a := range statusToDelete.AttachmentIDs {
|
||||
if _, err := p.media.Unattach(ctx, statusToDelete.Account, a); err != nil {
|
||||
return err
|
||||
errs.Appendf("error unattaching media: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,44 +407,55 @@ func (p *Processor) wipeStatus(ctx context.Context, statusToDelete *gtsmodel.Sta
|
||||
// todo: p.state.DB.DeleteMentionsForStatus
|
||||
for _, id := range statusToDelete.MentionIDs {
|
||||
if err := p.state.DB.DeleteMentionByID(ctx, id); err != nil {
|
||||
return err
|
||||
errs.Appendf("error deleting status mention: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// delete all notification entries generated by this status
|
||||
if err := p.state.DB.DeleteNotificationsForStatus(ctx, statusToDelete.ID); err != nil {
|
||||
return err
|
||||
errs.Appendf("error deleting status notifications: %w", err)
|
||||
}
|
||||
|
||||
// delete all bookmarks that point to this status
|
||||
if err := p.state.DB.DeleteStatusBookmarksForStatus(ctx, statusToDelete.ID); err != nil {
|
||||
return err
|
||||
errs.Appendf("error deleting status bookmarks: %w", err)
|
||||
}
|
||||
|
||||
// delete all faves of this status
|
||||
if err := p.state.DB.DeleteStatusFavesForStatus(ctx, statusToDelete.ID); err != nil {
|
||||
return err
|
||||
errs.Appendf("error deleting status faves: %w", err)
|
||||
}
|
||||
|
||||
// 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.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.state.DB.DeleteStatusByID(ctx, b.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
boosts, err := p.state.DB.GetStatusBoosts(
|
||||
// we MUST set a barebones context here,
|
||||
// as depending on where it came from the
|
||||
// original BoostOf may already be gone.
|
||||
gtscontext.SetBarebones(ctx),
|
||||
statusToDelete.ID)
|
||||
if err != nil {
|
||||
errs.Appendf("error fetching status boosts: %w", err)
|
||||
}
|
||||
for _, b := range boosts {
|
||||
if err := p.deleteStatusFromTimelines(ctx, b.ID); err != nil {
|
||||
errs.Appendf("error deleting boost from timelines: %w", err)
|
||||
}
|
||||
if err := p.state.DB.DeleteStatusByID(ctx, b.ID); err != nil {
|
||||
errs.Appendf("error deleting boost: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// delete this status from any and all timelines
|
||||
if err := p.deleteStatusFromTimelines(ctx, statusToDelete.ID); err != nil {
|
||||
return err
|
||||
errs.Appendf("error deleting status from timelines: %w", err)
|
||||
}
|
||||
|
||||
// delete the status itself
|
||||
return p.state.DB.DeleteStatusByID(ctx, statusToDelete.ID)
|
||||
// finally, delete the status itself
|
||||
if err := p.state.DB.DeleteStatusByID(ctx, statusToDelete.ID); err != nil {
|
||||
errs.Appendf("error deleting status: %w", err)
|
||||
}
|
||||
|
||||
return errs.Combine()
|
||||
}
|
||||
|
||||
// deleteStatusFromTimelines completely removes the given status from all timelines.
|
||||
|
@@ -106,47 +106,24 @@ func (p *Processor) BoostRemove(ctx context.Context, requestingAccount *gtsmodel
|
||||
return nil, gtserror.NewErrorNotFound(errors.New("status is not visible"))
|
||||
}
|
||||
|
||||
// check if we actually have a boost for this status
|
||||
var toUnboost bool
|
||||
|
||||
gtsBoost := >smodel.Status{}
|
||||
where := []db.Where{
|
||||
{
|
||||
Key: "boost_of_id",
|
||||
Value: targetStatusID,
|
||||
},
|
||||
{
|
||||
Key: "account_id",
|
||||
Value: requestingAccount.ID,
|
||||
},
|
||||
}
|
||||
err = p.state.DB.GetWhere(ctx, where, gtsBoost)
|
||||
if err == nil {
|
||||
// we have a boost
|
||||
toUnboost = true
|
||||
}
|
||||
|
||||
// Check whether the requesting account has boosted the given status ID.
|
||||
boost, err := p.state.DB.GetStatusBoost(ctx, targetStatusID, requestingAccount.ID)
|
||||
if err != nil {
|
||||
// something went wrong in the db finding the boost
|
||||
if err != db.ErrNoEntries {
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error fetching existing boost from database: %s", err))
|
||||
}
|
||||
// we just don't have a boost
|
||||
toUnboost = false
|
||||
return nil, gtserror.NewErrorNotFound(fmt.Errorf("error checking status boost %s: %w", targetStatusID, err))
|
||||
}
|
||||
|
||||
if toUnboost {
|
||||
if boost != nil {
|
||||
// pin some stuff onto the boost while we have it out of the db
|
||||
gtsBoost.Account = requestingAccount
|
||||
gtsBoost.BoostOf = targetStatus
|
||||
gtsBoost.BoostOfAccount = targetStatus.Account
|
||||
gtsBoost.BoostOf.Account = targetStatus.Account
|
||||
boost.Account = requestingAccount
|
||||
boost.BoostOf = targetStatus
|
||||
boost.BoostOfAccount = targetStatus.Account
|
||||
boost.BoostOf.Account = targetStatus.Account
|
||||
|
||||
// send it back to the processor for async processing
|
||||
p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{
|
||||
APObjectType: ap.ActivityAnnounce,
|
||||
APActivityType: ap.ActivityUndo,
|
||||
GTSModel: gtsBoost,
|
||||
GTSModel: boost,
|
||||
OriginAccount: requestingAccount,
|
||||
TargetAccount: targetStatus.Account,
|
||||
})
|
||||
@@ -189,15 +166,15 @@ func (p *Processor) StatusBoostedBy(ctx context.Context, requestingAccount *gtsm
|
||||
return nil, gtserror.NewErrorNotFound(err)
|
||||
}
|
||||
|
||||
statusReblogs, err := p.state.DB.GetStatusReblogs(ctx, targetStatus)
|
||||
statusBoosts, err := p.state.DB.GetStatusBoosts(ctx, targetStatus.ID)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("BoostedBy: error seeing who boosted status: %s", err)
|
||||
return nil, gtserror.NewErrorNotFound(err)
|
||||
}
|
||||
|
||||
// filter account IDs so the user doesn't see accounts they blocked or which blocked them
|
||||
accountIDs := make([]string, 0, len(statusReblogs))
|
||||
for _, s := range statusReblogs {
|
||||
accountIDs := make([]string, 0, len(statusBoosts))
|
||||
for _, s := range statusBoosts {
|
||||
blocked, err := p.state.DB.IsEitherBlocked(ctx, requestingAccount.ID, s.AccountID)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("BoostedBy: error checking blocks: %s", err)
|
||||
|
@@ -112,7 +112,7 @@ func (p *Processor) FavedBy(ctx context.Context, requestingAccount *gtsmodel.Acc
|
||||
return nil, errWithCode
|
||||
}
|
||||
|
||||
statusFaves, err := p.state.DB.GetStatusFavesForStatus(ctx, targetStatus.ID)
|
||||
statusFaves, err := p.state.DB.GetStatusFaves(ctx, targetStatus.ID)
|
||||
if err != nil {
|
||||
return nil, gtserror.NewErrorNotFound(fmt.Errorf("FavedBy: error seeing who faved status: %s", err))
|
||||
}
|
||||
|
Reference in New Issue
Block a user