[bugfix] Deref stats async, serve stub collections if handshaking (#2990)

* [bugfix] Deref stats async, allow peek if handshaking

* don't return totalItems when handshaking or hiding collections

* use GetLimit()

* use StubAccountStats
This commit is contained in:
tobi 2024-06-11 11:54:59 +02:00 committed by GitHub
commit 611f9de39b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 412 additions and 261 deletions

View file

@ -102,11 +102,15 @@ func (d *Dereferencer) GetAccountByURI(ctx context.Context, requestUser string,
}
if accountable != nil {
// This account was updated, enqueue re-dereference featured posts.
// This account was updated, enqueue re-dereference featured posts + stats.
d.state.Workers.Dereference.Queue.Push(func(ctx context.Context) {
if err := d.dereferenceAccountFeatured(ctx, requestUser, account); err != nil {
log.Errorf(ctx, "error fetching account featured collection: %v", err)
}
if err := d.dereferenceAccountStats(ctx, requestUser, account); err != nil {
log.Errorf(ctx, "error fetching account stats: %v", err)
}
})
}
@ -150,11 +154,22 @@ func (d *Dereferencer) getAccountByURI(ctx context.Context, requestUser string,
}
// Create and pass-through a new bare-bones model for dereferencing.
return d.enrichAccountSafely(ctx, requestUser, uri, &gtsmodel.Account{
account, accountable, err := d.enrichAccountSafely(ctx, requestUser, uri, &gtsmodel.Account{
ID: id.NewULID(),
Domain: uri.Host,
URI: uriStr,
}, nil)
if err != nil {
return nil, nil, err
}
// We have a new account. Ensure basic account stats populated;
// real stats will be fetched from remote asynchronously.
if err := d.state.DB.StubAccountStats(ctx, account); err != nil {
return nil, nil, gtserror.Newf("error stubbing account stats: %w", err)
}
return account, accountable, nil
}
if accountFresh(account, nil) {
@ -199,11 +214,15 @@ func (d *Dereferencer) GetAccountByUsernameDomain(ctx context.Context, requestUs
}
if accountable != nil {
// This account was updated, enqueue re-dereference featured posts.
// This account was updated, enqueue re-dereference featured posts + stats.
d.state.Workers.Dereference.Queue.Push(func(ctx context.Context) {
if err := d.dereferenceAccountFeatured(ctx, requestUser, account); err != nil {
log.Errorf(ctx, "error fetching account featured collection: %v", err)
}
if err := d.dereferenceAccountStats(ctx, requestUser, account); err != nil {
log.Errorf(ctx, "error fetching account stats: %v", err)
}
})
}
@ -251,6 +270,12 @@ func (d *Dereferencer) getAccountByUsernameDomain(
return nil, nil, err
}
// We have a new account. Ensure basic account stats populated;
// real stats will be fetched from remote asynchronously.
if err := d.state.DB.StubAccountStats(ctx, account); err != nil {
return nil, nil, gtserror.Newf("error stubbing account stats: %w", err)
}
return account, accountable, nil
}
@ -320,11 +345,15 @@ func (d *Dereferencer) RefreshAccount(
}
if accountable != nil {
// This account was updated, enqueue re-dereference featured posts.
// This account was updated, enqueue re-dereference featured posts + stats.
d.state.Workers.Dereference.Queue.Push(func(ctx context.Context) {
if err := d.dereferenceAccountFeatured(ctx, requestUser, latest); err != nil {
log.Errorf(ctx, "error fetching account featured collection: %v", err)
}
if err := d.dereferenceAccountStats(ctx, requestUser, latest); err != nil {
log.Errorf(ctx, "error fetching account stats: %v", err)
}
})
}
@ -369,10 +398,14 @@ func (d *Dereferencer) RefreshAccountAsync(
}
if accountable != nil {
// This account was updated, enqueue re-dereference featured posts.
// This account was updated, enqueue re-dereference featured posts + stats.
if err := d.dereferenceAccountFeatured(ctx, requestUser, latest); err != nil {
log.Errorf(ctx, "error fetching account featured collection: %v", err)
}
if err := d.dereferenceAccountStats(ctx, requestUser, latest); err != nil {
log.Errorf(ctx, "error fetching account stats: %v", err)
}
}
})
}
@ -697,12 +730,12 @@ func (d *Dereferencer) enrichAccount(
latestAcc.ID = account.ID
latestAcc.FetchedAt = time.Now()
// Ensure the account's avatar media is populated, passing in existing to check for chages.
// Ensure the account's avatar media is populated, passing in existing to check for changes.
if err := d.fetchRemoteAccountAvatar(ctx, tsport, account, latestAcc); err != nil {
log.Errorf(ctx, "error fetching remote avatar for account %s: %v", uri, err)
}
// Ensure the account's avatar media is populated, passing in existing to check for chages.
// Ensure the account's avatar media is populated, passing in existing to check for changes.
if err := d.fetchRemoteAccountHeader(ctx, tsport, account, latestAcc); err != nil {
log.Errorf(ctx, "error fetching remote header for account %s: %v", uri, err)
}
@ -712,11 +745,6 @@ func (d *Dereferencer) enrichAccount(
log.Errorf(ctx, "error fetching remote emojis for account %s: %v", uri, err)
}
// Fetch followers/following count for this account.
if err := d.fetchRemoteAccountStats(ctx, latestAcc, requestUser); err != nil {
log.Errorf(ctx, "error fetching remote stats for account %s: %v", uri, err)
}
if account.IsNew() {
// Prefer published/created time from
// apubAcc, fall back to FetchedAt value.
@ -1007,7 +1035,7 @@ func (d *Dereferencer) fetchRemoteAccountEmojis(ctx context.Context, targetAccou
return changed, nil
}
func (d *Dereferencer) fetchRemoteAccountStats(ctx context.Context, account *gtsmodel.Account, requestUser string) error {
func (d *Dereferencer) dereferenceAccountStats(ctx context.Context, requestUser string, account *gtsmodel.Account) error {
// Ensure we have a stats model for this account.
if account.Stats == nil {
if err := d.state.DB.PopulateAccountStats(ctx, account); err != nil {