[performance] use GetAccountByUsernameDomain() for local account lookups to rely on cache (#793)

Signed-off-by: kim <grufwub@gmail.com>

Signed-off-by: kim <grufwub@gmail.com>
This commit is contained in:
kim 2022-09-02 10:56:33 +01:00 committed by GitHub
parent 1e1cdee06a
commit 614ab12733
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 29 additions and 42 deletions

View file

@ -87,7 +87,7 @@
return err return err
} }
a, err := dbConn.GetLocalAccountByUsername(ctx, username) a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
if err != nil { if err != nil {
return err return err
} }
@ -125,7 +125,7 @@
return err return err
} }
a, err := dbConn.GetLocalAccountByUsername(ctx, username) a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
if err != nil { if err != nil {
return err return err
} }
@ -161,7 +161,7 @@
return err return err
} }
a, err := dbConn.GetLocalAccountByUsername(ctx, username) a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
if err != nil { if err != nil {
return err return err
} }
@ -197,7 +197,7 @@
return err return err
} }
a, err := dbConn.GetLocalAccountByUsername(ctx, username) a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
if err != nil { if err != nil {
return err return err
} }
@ -247,7 +247,7 @@
return err return err
} }
a, err := dbConn.GetLocalAccountByUsername(ctx, username) a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
if err != nil { if err != nil {
return err return err
} }

View file

@ -42,9 +42,6 @@ type Account interface {
// UpdateAccount updates one account by ID. // UpdateAccount updates one account by ID.
UpdateAccount(ctx context.Context, account *gtsmodel.Account) (*gtsmodel.Account, Error) UpdateAccount(ctx context.Context, account *gtsmodel.Account) (*gtsmodel.Account, Error)
// GetLocalAccountByUsername returns an account on this instance by its username.
GetLocalAccountByUsername(ctx context.Context, username string) (*gtsmodel.Account, Error)
// GetAccountFaves fetches faves/likes created by the target accountID. // GetAccountFaves fetches faves/likes created by the target accountID.
GetAccountFaves(ctx context.Context, accountID string) ([]*gtsmodel.StatusFave, Error) GetAccountFaves(ctx context.Context, accountID string) ([]*gtsmodel.StatusFave, Error)

View file

@ -91,11 +91,13 @@ func() (*gtsmodel.Account, bool) {
return a.cache.GetByUsernameDomain(username, domain) return a.cache.GetByUsernameDomain(username, domain)
}, },
func(account *gtsmodel.Account) error { func(account *gtsmodel.Account) error {
q := a.newAccountQ(account).Where("account.username = ?", username) q := a.newAccountQ(account)
if domain != "" { if domain != "" {
q = q.Where("account.username = ?", username)
q = q.Where("account.domain = ?", domain) q = q.Where("account.domain = ?", domain)
} else { } else {
q = q.Where("account.username = ?", strings.ToLower(username))
q = q.Where("account.domain IS NULL") q = q.Where("account.domain IS NULL")
} }
@ -217,19 +219,6 @@ func (a *accountDB) SetAccountHeaderOrAvatar(ctx context.Context, mediaAttachmen
return nil return nil
} }
func (a *accountDB) GetLocalAccountByUsername(ctx context.Context, username string) (*gtsmodel.Account, db.Error) {
account := new(gtsmodel.Account)
q := a.newAccountQ(account).
Where("username = ?", strings.ToLower(username)). // usernames on our instance will always be lowercase
WhereGroup(" AND ", whereEmptyOrNull("domain"))
if err := q.Scan(ctx); err != nil {
return nil, a.conn.ProcessError(err)
}
return account, nil
}
func (a *accountDB) GetAccountFaves(ctx context.Context, accountID string) ([]*gtsmodel.StatusFave, db.Error) { func (a *accountDB) GetAccountFaves(ctx context.Context, accountID string) ([]*gtsmodel.StatusFave, db.Error) {
faves := new([]*gtsmodel.StatusFave) faves := new([]*gtsmodel.StatusFave)

View file

@ -127,7 +127,7 @@ func (d *deref) GetRemoteAccount(ctx context.Context, params GetRemoteAccountPar
// to be a local account, so don't resolve // to be a local account, so don't resolve
skipResolve = true skipResolve = true
if a, dbErr := d.db.GetLocalAccountByUsername(ctx, params.RemoteAccountUsername); dbErr == nil { if a, dbErr := d.db.GetAccountByUsernameDomain(ctx, params.RemoteAccountUsername, ""); dbErr == nil {
foundAccount = a foundAccount = a
} else if dbErr != db.ErrNoEntries { } else if dbErr != db.ErrNoEntries {
err = fmt.Errorf("GetRemoteAccount: database error looking for local account with username %s: %s", params.RemoteAccountUsername, err) err = fmt.Errorf("GetRemoteAccount: database error looking for local account with username %s: %s", params.RemoteAccountUsername, err)

View file

@ -85,7 +85,7 @@ func (f *federatingDB) InboxesForIRI(c context.Context, iri *url.URL) (inboxIRIs
return nil, fmt.Errorf("couldn't extract local account username from uri %s: %s", iri, err) return nil, fmt.Errorf("couldn't extract local account username from uri %s: %s", iri, err)
} }
account, err := f.db.GetLocalAccountByUsername(c, localAccountUsername) account, err := f.db.GetAccountByUsernameDomain(c, localAccountUsername, "")
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't find local account with username %s: %s", localAccountUsername, err) return nil, fmt.Errorf("couldn't find local account with username %s: %s", localAccountUsername, err)
} }

View file

@ -70,7 +70,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
} }
if _, err := f.db.GetLocalAccountByUsername(ctx, username); err != nil { if _, err := f.db.GetAccountByUsernameDomain(ctx, username, ""); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
// there are no entries for this username // there are no entries for this username
return false, nil return false, nil
@ -87,7 +87,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
} }
if _, err := f.db.GetLocalAccountByUsername(ctx, username); err != nil { if _, err := f.db.GetAccountByUsernameDomain(ctx, username, ""); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
// there are no entries for this username // there are no entries for this username
return false, nil return false, nil
@ -104,7 +104,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
} }
if _, err := f.db.GetLocalAccountByUsername(ctx, username); err != nil { if _, err := f.db.GetAccountByUsernameDomain(ctx, username, ""); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
// there are no entries for this username // there are no entries for this username
return false, nil return false, nil
@ -121,7 +121,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing like path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing like path for url %s: %s", id.String(), err)
} }
if _, err := f.db.GetLocalAccountByUsername(ctx, username); err != nil { if _, err := f.db.GetAccountByUsernameDomain(ctx, username, ""); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
// there are no entries for this username // there are no entries for this username
return false, nil return false, nil
@ -146,7 +146,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing block path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing block path for url %s: %s", id.String(), err)
} }
if _, err := f.db.GetLocalAccountByUsername(ctx, username); err != nil { if _, err := f.db.GetAccountByUsernameDomain(ctx, username, ""); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
// there are no entries for this username // there are no entries for this username
return false, nil return false, nil

View file

@ -157,7 +157,7 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr
return nil, false, errors.New("username was empty") return nil, false, errors.New("username was empty")
} }
receivingAccount, err := f.db.GetLocalAccountByUsername(ctx, username) receivingAccount, err := f.db.GetAccountByUsernameDomain(ctx, username, "")
if err != nil { if err != nil {
return nil, false, fmt.Errorf("could not fetch receiving account with username %s: %s", username, err) return nil, false, fmt.Errorf("could not fetch receiving account with username %s: %s", username, err)
} }

View file

@ -44,7 +44,7 @@ func (p *processor) Get(ctx context.Context, requestingAccount *gtsmodel.Account
} }
func (p *processor) GetLocalByUsername(ctx context.Context, requestingAccount *gtsmodel.Account, username string) (*apimodel.Account, gtserror.WithCode) { func (p *processor) GetLocalByUsername(ctx context.Context, requestingAccount *gtsmodel.Account, username string) (*apimodel.Account, gtserror.WithCode) {
targetAccount, err := p.db.GetLocalAccountByUsername(ctx, username) targetAccount, err := p.db.GetAccountByUsernameDomain(ctx, username, "")
if err != nil { if err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
return nil, gtserror.NewErrorNotFound(errors.New("account not found")) return nil, gtserror.NewErrorNotFound(errors.New("account not found"))

View file

@ -30,7 +30,7 @@
func (p *processor) GetFollowers(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) { func (p *processor) GetFollowers(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
// get the account the request is referring to // get the account the request is referring to
requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "")
if err != nil { if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
} }

View file

@ -30,7 +30,7 @@
func (p *processor) GetFollowing(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) { func (p *processor) GetFollowing(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
// get the account the request is referring to // get the account the request is referring to
requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "")
if err != nil { if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
} }

View file

@ -31,7 +31,7 @@
func (p *processor) GetOutbox(ctx context.Context, requestedUsername string, page bool, maxID string, minID string, requestURL *url.URL) (interface{}, gtserror.WithCode) { func (p *processor) GetOutbox(ctx context.Context, requestedUsername string, page bool, maxID string, minID string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
// get the account the request is referring to // get the account the request is referring to
requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "")
if err != nil { if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
} }

View file

@ -30,7 +30,7 @@
func (p *processor) GetStatus(ctx context.Context, requestedUsername string, requestedStatusID string, requestURL *url.URL) (interface{}, gtserror.WithCode) { func (p *processor) GetStatus(ctx context.Context, requestedUsername string, requestedStatusID string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
// get the account the request is referring to // get the account the request is referring to
requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "")
if err != nil { if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
} }

View file

@ -32,7 +32,7 @@
func (p *processor) GetStatusReplies(ctx context.Context, requestedUsername string, requestedStatusID string, page bool, onlyOtherAccounts bool, minID string, requestURL *url.URL) (interface{}, gtserror.WithCode) { func (p *processor) GetStatusReplies(ctx context.Context, requestedUsername string, requestedStatusID string, page bool, onlyOtherAccounts bool, minID string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
// get the account the request is referring to // get the account the request is referring to
requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "")
if err != nil { if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
} }

View file

@ -32,7 +32,7 @@
func (p *processor) GetUser(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) { func (p *processor) GetUser(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
// get the account the request is referring to // get the account the request is referring to
requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "")
if err != nil { if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
} }

View file

@ -37,7 +37,7 @@
func (p *processor) GetWebfingerAccount(ctx context.Context, requestedUsername string) (*apimodel.WellKnownResponse, gtserror.WithCode) { func (p *processor) GetWebfingerAccount(ctx context.Context, requestedUsername string) (*apimodel.WellKnownResponse, gtserror.WithCode) {
// get the account the request is referring to // get the account the request is referring to
requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "")
if err != nil { if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
} }

View file

@ -137,7 +137,7 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe
// validate & update site contact account if it's set on the form // validate & update site contact account if it's set on the form
if form.ContactUsername != nil { if form.ContactUsername != nil {
// make sure the account with the given username exists in the db // make sure the account with the given username exists in the db
contactAccount, err := p.db.GetLocalAccountByUsername(ctx, *form.ContactUsername) contactAccount, err := p.db.GetAccountByUsernameDomain(ctx, *form.ContactUsername, "")
if err != nil { if err != nil {
return nil, gtserror.NewErrorBadRequest(err, fmt.Sprintf("account with username %s not retrievable", *form.ContactUsername)) return nil, gtserror.NewErrorBadRequest(err, fmt.Sprintf("account with username %s not retrievable", *form.ContactUsername))
} }

View file

@ -193,7 +193,7 @@ func (p *processor) searchAccountByURI(ctx context.Context, authed *oauth.Auth,
func (p *processor) searchAccountByMention(ctx context.Context, authed *oauth.Auth, username string, domain string, resolve bool) (*gtsmodel.Account, error) { func (p *processor) searchAccountByMention(ctx context.Context, authed *oauth.Auth, username string, domain string, resolve bool) (*gtsmodel.Account, error) {
// if it's a local account we can skip a whole bunch of stuff // if it's a local account we can skip a whole bunch of stuff
if domain == config.GetHost() || domain == config.GetAccountDomain() || domain == "" { if domain == config.GetHost() || domain == config.GetAccountDomain() || domain == "" {
maybeAcct, err := p.db.GetLocalAccountByUsername(ctx, username) maybeAcct, err := p.db.GetAccountByUsernameDomain(ctx, username, "")
if err == nil || err == db.ErrNoEntries { if err == nil || err == db.ErrNoEntries {
return maybeAcct, nil return maybeAcct, nil
} }

View file

@ -46,7 +46,7 @@ func GetParseMentionFunc(dbConn db.DB, federator federation.Federator) gtsmodel.
var mentionedAccount *gtsmodel.Account var mentionedAccount *gtsmodel.Account
if domain == "" || domain == config.GetHost() || domain == config.GetAccountDomain() { if domain == "" || domain == config.GetHost() || domain == config.GetAccountDomain() {
localAccount, err := dbConn.GetLocalAccountByUsername(ctx, username) localAccount, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -129,7 +129,7 @@ func (c *controller) NewTransportForUsername(ctx context.Context, username strin
u = username u = username
} }
ourAccount, err := c.db.GetLocalAccountByUsername(ctx, u) ourAccount, err := c.db.GetAccountByUsernameDomain(ctx, u, "")
if err != nil { if err != nil {
return nil, fmt.Errorf("error getting account %s from db: %s", username, err) return nil, fmt.Errorf("error getting account %s from db: %s", username, err)
} }
@ -138,6 +138,7 @@ func (c *controller) NewTransportForUsername(ctx context.Context, username strin
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating transport for user %s: %s", username, err) return nil, fmt.Errorf("error creating transport for user %s: %s", username, err)
} }
return transport, nil return transport, nil
} }