[chore] move PopulateAccountStats() nil check often performed into function itself (#3158)

* move PopulateAccountStats() nil check often performed into function itself

* fix test to take in mind we don't repopulate account stats if not-nil
This commit is contained in:
kim 2024-08-02 12:15:11 +00:00 committed by GitHub
parent 94e87610c4
commit 0f734a2410
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 53 additions and 78 deletions

View file

@ -712,12 +712,10 @@ func (a *accountDB) PopulateAccount(ctx context.Context, account *gtsmodel.Accou
} }
} }
if account.Stats == nil { // Get / Create stats for this account (handles case of already set).
// Get / Create stats for this account.
if err := a.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := a.state.DB.PopulateAccountStats(ctx, account); err != nil {
errs.Appendf("error populating account stats: %w", err) errs.Appendf("error populating account stats: %w", err)
} }
}
return errs.Combine() return errs.Combine()
} }
@ -1160,6 +1158,11 @@ func (a *accountDB) UpdateAccountSettings(
} }
func (a *accountDB) PopulateAccountStats(ctx context.Context, account *gtsmodel.Account) error { func (a *accountDB) PopulateAccountStats(ctx context.Context, account *gtsmodel.Account) error {
if account.Stats != nil {
// Already populated!
return nil
}
// Fetch stats from db cache with loader callback. // Fetch stats from db cache with loader callback.
stats, err := a.state.Caches.DB.AccountStats.LoadOne( stats, err := a.state.Caches.DB.AccountStats.LoadOne(
"AccountID", "AccountID",

View file

@ -743,6 +743,10 @@ func (suite *AccountTestSuite) TestAccountStatsAll() {
suite.FailNow(err.Error()) suite.FailNow(err.Error())
} }
// Nil out account stats to allow
// db to refetch + regenerate them.
account.Stats = nil
// Get stats for a third time, they // Get stats for a third time, they
// should get regenerated now, but // should get regenerated now, but
// only for local accounts. // only for local accounts.

View file

@ -984,11 +984,9 @@ func (d *Dereferencer) dereferenceAccountStats(
account *gtsmodel.Account, account *gtsmodel.Account,
) error { ) error {
// Ensure we have a stats model for this account. // Ensure we have a stats model for this account.
if account.Stats == nil {
if err := d.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := d.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// We want to update stats by getting remote // We want to update stats by getting remote
// followers/following/statuses counts for // followers/following/statuses counts for

View file

@ -70,12 +70,10 @@ func (p *Processor) GetRSSFeedForUsername(ctx context.Context, username string)
} }
// Ensure account stats populated. // Ensure account stats populated.
if account.Stats == nil {
if err := p.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := p.state.DB.PopulateAccountStats(ctx, account); err != nil {
err = gtserror.Newf("db error getting account stats %s: %w", username, err) err = gtserror.Newf("db error getting account stats %s: %w", username, err)
return nil, never, gtserror.NewErrorInternalError(err) return nil, never, gtserror.NewErrorInternalError(err)
} }
}
// LastModified time is needed by callers to check freshness for cacheing. // LastModified time is needed by callers to check freshness for cacheing.
// This might be a zero time.Time if account has never posted a status that's // This might be a zero time.Time if account has never posted a status that's

View file

@ -70,12 +70,10 @@ func (p *Processor) OutboxGet(
} }
// Ensure we have stats for this account. // Ensure we have stats for this account.
if receivingAcct.Stats == nil {
if err := p.state.DB.PopulateAccountStats(ctx, receivingAcct); err != nil { if err := p.state.DB.PopulateAccountStats(ctx, receivingAcct); err != nil {
err := gtserror.Newf("error getting stats for account %s: %w", receivingAcct.ID, err) err := gtserror.Newf("error getting stats for account %s: %w", receivingAcct.ID, err)
return nil, gtserror.NewErrorInternalError(err) return nil, gtserror.NewErrorInternalError(err)
} }
}
var obj vocab.Type var obj vocab.Type
@ -200,12 +198,10 @@ func (p *Processor) FollowersGet(
} }
// Ensure we have stats for this account. // Ensure we have stats for this account.
if receivingAcct.Stats == nil {
if err := p.state.DB.PopulateAccountStats(ctx, receivingAcct); err != nil { if err := p.state.DB.PopulateAccountStats(ctx, receivingAcct); err != nil {
err := gtserror.Newf("error getting stats for account %s: %w", receivingAcct.ID, err) err := gtserror.Newf("error getting stats for account %s: %w", receivingAcct.ID, err)
return nil, gtserror.NewErrorInternalError(err) return nil, gtserror.NewErrorInternalError(err)
} }
}
var obj vocab.Type var obj vocab.Type
@ -314,12 +310,10 @@ func (p *Processor) FollowingGet(ctx context.Context, requestedUser string, page
} }
// Ensure we have stats for this account. // Ensure we have stats for this account.
if receivingAcct.Stats == nil {
if err := p.state.DB.PopulateAccountStats(ctx, receivingAcct); err != nil { if err := p.state.DB.PopulateAccountStats(ctx, receivingAcct); err != nil {
err := gtserror.Newf("error getting stats for account %s: %w", receivingAcct.ID, err) err := gtserror.Newf("error getting stats for account %s: %w", receivingAcct.ID, err)
return nil, gtserror.NewErrorInternalError(err) return nil, gtserror.NewErrorInternalError(err)
} }
}
var obj vocab.Type var obj vocab.Type

View file

@ -92,12 +92,10 @@ func (p *Processor) PinCreate(ctx context.Context, requestingAccount *gtsmodel.A
} }
// Ensure account stats populated. // Ensure account stats populated.
if requestingAccount.Stats == nil {
if err := p.state.DB.PopulateAccountStats(ctx, requestingAccount); err != nil { if err := p.state.DB.PopulateAccountStats(ctx, requestingAccount); err != nil {
err = gtserror.Newf("db error getting account stats: %w", err) err = gtserror.Newf("db error getting account stats: %w", err)
return nil, gtserror.NewErrorInternalError(err) return nil, gtserror.NewErrorInternalError(err)
} }
}
pinnedCount := *requestingAccount.Stats.StatusesPinnedCount pinnedCount := *requestingAccount.Stats.StatusesPinnedCount
if pinnedCount >= allowedPinnedCount { if pinnedCount >= allowedPinnedCount {
@ -157,12 +155,10 @@ func (p *Processor) PinRemove(ctx context.Context, requestingAccount *gtsmodel.A
} }
// Ensure account stats populated. // Ensure account stats populated.
if requestingAccount.Stats == nil {
if err := p.state.DB.PopulateAccountStats(ctx, requestingAccount); err != nil { if err := p.state.DB.PopulateAccountStats(ctx, requestingAccount); err != nil {
err = gtserror.Newf("db error getting account stats: %w", err) err = gtserror.Newf("db error getting account stats: %w", err)
return nil, gtserror.NewErrorInternalError(err) return nil, gtserror.NewErrorInternalError(err)
} }
}
targetStatus.PinnedAt = time.Time{} targetStatus.PinnedAt = time.Time{}
if err := p.state.DB.UpdateStatus(ctx, targetStatus, "pinned_at"); err != nil { if err := p.state.DB.UpdateStatus(ctx, targetStatus, "pinned_at"); err != nil {

View file

@ -257,11 +257,9 @@ func (u *utils) incrementStatusesCount(
defer unlock() defer unlock()
// Populate stats. // Populate stats.
if account.Stats == nil {
if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// Update stats by incrementing status // Update stats by incrementing status
// count by one and setting last posted. // count by one and setting last posted.
@ -288,11 +286,9 @@ func (u *utils) decrementStatusesCount(
defer unlock() defer unlock()
// Populate stats. // Populate stats.
if account.Stats == nil {
if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// Update stats by decrementing // Update stats by decrementing
// status count by one. // status count by one.
@ -322,11 +318,9 @@ func (u *utils) incrementFollowersCount(
defer unlock() defer unlock()
// Populate stats. // Populate stats.
if account.Stats == nil {
if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// Update stats by incrementing followers // Update stats by incrementing followers
// count by one and setting last posted. // count by one and setting last posted.
@ -351,11 +345,9 @@ func (u *utils) decrementFollowersCount(
defer unlock() defer unlock()
// Populate stats. // Populate stats.
if account.Stats == nil {
if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// Update stats by decrementing // Update stats by decrementing
// followers count by one. // followers count by one.
@ -385,11 +377,9 @@ func (u *utils) incrementFollowingCount(
defer unlock() defer unlock()
// Populate stats. // Populate stats.
if account.Stats == nil {
if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// Update stats by incrementing // Update stats by incrementing
// followers count by one. // followers count by one.
@ -414,11 +404,9 @@ func (u *utils) decrementFollowingCount(
defer unlock() defer unlock()
// Populate stats. // Populate stats.
if account.Stats == nil {
if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// Update stats by decrementing // Update stats by decrementing
// following count by one. // following count by one.
@ -448,11 +436,9 @@ func (u *utils) incrementFollowRequestsCount(
defer unlock() defer unlock()
// Populate stats. // Populate stats.
if account.Stats == nil {
if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// Update stats by incrementing // Update stats by incrementing
// follow requests count by one. // follow requests count by one.
@ -477,11 +463,9 @@ func (u *utils) decrementFollowRequestsCount(
defer unlock() defer unlock()
// Populate stats. // Populate stats.
if account.Stats == nil {
if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil { if err := u.state.DB.PopulateAccountStats(ctx, account); err != nil {
return gtserror.Newf("db error getting account stats: %w", err) return gtserror.Newf("db error getting account stats: %w", err)
} }
}
// Update stats by decrementing // Update stats by decrementing
// follow requests count by one. // follow requests count by one.

View file

@ -113,14 +113,12 @@ func (c *Converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmode
} }
// Ensure account stats populated. // Ensure account stats populated.
if a.Stats == nil {
if err := c.state.DB.PopulateAccountStats(ctx, a); err != nil { if err := c.state.DB.PopulateAccountStats(ctx, a); err != nil {
return nil, gtserror.Newf( return nil, gtserror.Newf(
"error getting stats for account %s: %w", "error getting stats for account %s: %w",
a.ID, err, a.ID, err,
) )
} }
}
// Populate the account's role permissions bitmap and highlightedness from its public role. // Populate the account's role permissions bitmap and highlightedness from its public role.
if len(apiAccount.Roles) > 0 { if len(apiAccount.Roles) > 0 {