From 614ab12733b991dbea9d1f7fa311a98072558727 Mon Sep 17 00:00:00 2001 From: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> Date: Fri, 2 Sep 2022 10:56:33 +0100 Subject: [PATCH] [performance] use GetAccountByUsernameDomain() for local account lookups to rely on cache (#793) Signed-off-by: kim Signed-off-by: kim --- cmd/gotosocial/action/admin/account/account.go | 10 +++++----- internal/db/account.go | 3 --- internal/db/bundb/account.go | 17 +++-------------- internal/federation/dereferencing/account.go | 2 +- internal/federation/federatingdb/inbox.go | 2 +- internal/federation/federatingdb/owns.go | 10 +++++----- internal/federation/federatingprotocol.go | 2 +- internal/processing/account/get.go | 2 +- internal/processing/federation/getfollowers.go | 2 +- internal/processing/federation/getfollowing.go | 2 +- internal/processing/federation/getoutbox.go | 2 +- internal/processing/federation/getstatus.go | 2 +- .../processing/federation/getstatusreplies.go | 2 +- internal/processing/federation/getuser.go | 2 +- internal/processing/federation/getwebfinger.go | 2 +- internal/processing/instance.go | 2 +- internal/processing/search.go | 2 +- internal/processing/util.go | 2 +- internal/transport/controller.go | 3 ++- 19 files changed, 29 insertions(+), 42 deletions(-) diff --git a/cmd/gotosocial/action/admin/account/account.go b/cmd/gotosocial/action/admin/account/account.go index 83b98ac72..c5ac1073e 100644 --- a/cmd/gotosocial/action/admin/account/account.go +++ b/cmd/gotosocial/action/admin/account/account.go @@ -87,7 +87,7 @@ var Confirm action.GTSAction = func(ctx context.Context) error { return err } - a, err := dbConn.GetLocalAccountByUsername(ctx, username) + a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "") if err != nil { return err } @@ -125,7 +125,7 @@ var Promote action.GTSAction = func(ctx context.Context) error { return err } - a, err := dbConn.GetLocalAccountByUsername(ctx, username) + a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "") if err != nil { return err } @@ -161,7 +161,7 @@ var Demote action.GTSAction = func(ctx context.Context) error { return err } - a, err := dbConn.GetLocalAccountByUsername(ctx, username) + a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "") if err != nil { return err } @@ -197,7 +197,7 @@ var Disable action.GTSAction = func(ctx context.Context) error { return err } - a, err := dbConn.GetLocalAccountByUsername(ctx, username) + a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "") if err != nil { return err } @@ -247,7 +247,7 @@ var Password action.GTSAction = func(ctx context.Context) error { return err } - a, err := dbConn.GetLocalAccountByUsername(ctx, username) + a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "") if err != nil { return err } diff --git a/internal/db/account.go b/internal/db/account.go index 155bd666c..54e24784f 100644 --- a/internal/db/account.go +++ b/internal/db/account.go @@ -42,9 +42,6 @@ type Account interface { // UpdateAccount updates one account by ID. 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(ctx context.Context, accountID string) ([]*gtsmodel.StatusFave, Error) diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go index f46143401..7bee375e3 100644 --- a/internal/db/bundb/account.go +++ b/internal/db/bundb/account.go @@ -91,11 +91,13 @@ func (a *accountDB) GetAccountByUsernameDomain(ctx context.Context, username str return a.cache.GetByUsernameDomain(username, domain) }, func(account *gtsmodel.Account) error { - q := a.newAccountQ(account).Where("account.username = ?", username) + q := a.newAccountQ(account) if domain != "" { + q = q.Where("account.username = ?", username) q = q.Where("account.domain = ?", domain) } else { + q = q.Where("account.username = ?", strings.ToLower(username)) q = q.Where("account.domain IS NULL") } @@ -217,19 +219,6 @@ func (a *accountDB) SetAccountHeaderOrAvatar(ctx context.Context, mediaAttachmen 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) { faves := new([]*gtsmodel.StatusFave) diff --git a/internal/federation/dereferencing/account.go b/internal/federation/dereferencing/account.go index cbb9466ff..0fda96bf4 100644 --- a/internal/federation/dereferencing/account.go +++ b/internal/federation/dereferencing/account.go @@ -127,7 +127,7 @@ func (d *deref) GetRemoteAccount(ctx context.Context, params GetRemoteAccountPar // to be a local account, so don't resolve 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 } else if dbErr != db.ErrNoEntries { err = fmt.Errorf("GetRemoteAccount: database error looking for local account with username %s: %s", params.RemoteAccountUsername, err) diff --git a/internal/federation/federatingdb/inbox.go b/internal/federation/federatingdb/inbox.go index 8d8ffffed..b3b935bff 100644 --- a/internal/federation/federatingdb/inbox.go +++ b/internal/federation/federatingdb/inbox.go @@ -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) } - account, err := f.db.GetLocalAccountByUsername(c, localAccountUsername) + account, err := f.db.GetAccountByUsernameDomain(c, localAccountUsername, "") if err != nil { return nil, fmt.Errorf("couldn't find local account with username %s: %s", localAccountUsername, err) } diff --git a/internal/federation/federatingdb/owns.go b/internal/federation/federatingdb/owns.go index 6146f9c0a..c82dd847c 100644 --- a/internal/federation/federatingdb/owns.go +++ b/internal/federation/federatingdb/owns.go @@ -70,7 +70,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) { if err != nil { 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 { // there are no entries for this username return false, nil @@ -87,7 +87,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) { if err != nil { 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 { // there are no entries for this username return false, nil @@ -104,7 +104,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) { if err != nil { 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 { // there are no entries for this username return false, nil @@ -121,7 +121,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) { if err != nil { 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 { // there are no entries for this username return false, nil @@ -146,7 +146,7 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) { if err != nil { 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 { // there are no entries for this username return false, nil diff --git a/internal/federation/federatingprotocol.go b/internal/federation/federatingprotocol.go index 8242ca4b1..24dd471c2 100644 --- a/internal/federation/federatingprotocol.go +++ b/internal/federation/federatingprotocol.go @@ -157,7 +157,7 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr 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 { return nil, false, fmt.Errorf("could not fetch receiving account with username %s: %s", username, err) } diff --git a/internal/processing/account/get.go b/internal/processing/account/get.go index d6f1aa71f..c558b52ed 100644 --- a/internal/processing/account/get.go +++ b/internal/processing/account/get.go @@ -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) { - targetAccount, err := p.db.GetLocalAccountByUsername(ctx, username) + targetAccount, err := p.db.GetAccountByUsernameDomain(ctx, username, "") if err != nil { if err == db.ErrNoEntries { return nil, gtserror.NewErrorNotFound(errors.New("account not found")) diff --git a/internal/processing/federation/getfollowers.go b/internal/processing/federation/getfollowers.go index 30ec1c58f..89c229706 100644 --- a/internal/processing/federation/getfollowers.go +++ b/internal/processing/federation/getfollowers.go @@ -30,7 +30,7 @@ import ( func (p *processor) GetFollowers(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) { // 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 { return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) } diff --git a/internal/processing/federation/getfollowing.go b/internal/processing/federation/getfollowing.go index 13291939a..91f097817 100644 --- a/internal/processing/federation/getfollowing.go +++ b/internal/processing/federation/getfollowing.go @@ -30,7 +30,7 @@ import ( func (p *processor) GetFollowing(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) { // 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 { return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) } diff --git a/internal/processing/federation/getoutbox.go b/internal/processing/federation/getoutbox.go index b2e618b98..1a9afc14f 100644 --- a/internal/processing/federation/getoutbox.go +++ b/internal/processing/federation/getoutbox.go @@ -31,7 +31,7 @@ import ( 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 - requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) + requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "") if err != nil { return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) } diff --git a/internal/processing/federation/getstatus.go b/internal/processing/federation/getstatus.go index f61c87d1d..eff8881d8 100644 --- a/internal/processing/federation/getstatus.go +++ b/internal/processing/federation/getstatus.go @@ -30,7 +30,7 @@ import ( 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 - requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) + requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "") if err != nil { return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) } diff --git a/internal/processing/federation/getstatusreplies.go b/internal/processing/federation/getstatusreplies.go index fad986ea5..067fcb36b 100644 --- a/internal/processing/federation/getstatusreplies.go +++ b/internal/processing/federation/getstatusreplies.go @@ -32,7 +32,7 @@ import ( 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 - requestedAccount, err := p.db.GetLocalAccountByUsername(ctx, requestedUsername) + requestedAccount, err := p.db.GetAccountByUsernameDomain(ctx, requestedUsername, "") if err != nil { return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) } diff --git a/internal/processing/federation/getuser.go b/internal/processing/federation/getuser.go index 372a3a57b..c1ad9853b 100644 --- a/internal/processing/federation/getuser.go +++ b/internal/processing/federation/getuser.go @@ -32,7 +32,7 @@ import ( func (p *processor) GetUser(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) { // 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 { return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) } diff --git a/internal/processing/federation/getwebfinger.go b/internal/processing/federation/getwebfinger.go index 7158680d7..a1e1cb983 100644 --- a/internal/processing/federation/getwebfinger.go +++ b/internal/processing/federation/getwebfinger.go @@ -37,7 +37,7 @@ const ( func (p *processor) GetWebfingerAccount(ctx context.Context, requestedUsername string) (*apimodel.WellKnownResponse, gtserror.WithCode) { // 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 { return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err)) } diff --git a/internal/processing/instance.go b/internal/processing/instance.go index 0a13917ea..b7418659a 100644 --- a/internal/processing/instance.go +++ b/internal/processing/instance.go @@ -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 if form.ContactUsername != nil { // 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 { return nil, gtserror.NewErrorBadRequest(err, fmt.Sprintf("account with username %s not retrievable", *form.ContactUsername)) } diff --git a/internal/processing/search.go b/internal/processing/search.go index 2e5ec2025..3d7f3e56e 100644 --- a/internal/processing/search.go +++ b/internal/processing/search.go @@ -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) { // if it's a local account we can skip a whole bunch of stuff 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 { return maybeAcct, nil } diff --git a/internal/processing/util.go b/internal/processing/util.go index 76d1187f9..e360428cc 100644 --- a/internal/processing/util.go +++ b/internal/processing/util.go @@ -46,7 +46,7 @@ func GetParseMentionFunc(dbConn db.DB, federator federation.Federator) gtsmodel. var mentionedAccount *gtsmodel.Account if domain == "" || domain == config.GetHost() || domain == config.GetAccountDomain() { - localAccount, err := dbConn.GetLocalAccountByUsername(ctx, username) + localAccount, err := dbConn.GetAccountByUsernameDomain(ctx, username, "") if err != nil { return nil, err } diff --git a/internal/transport/controller.go b/internal/transport/controller.go index 255932d5d..5a72871d8 100644 --- a/internal/transport/controller.go +++ b/internal/transport/controller.go @@ -129,7 +129,7 @@ func (c *controller) NewTransportForUsername(ctx context.Context, username strin u = username } - ourAccount, err := c.db.GetLocalAccountByUsername(ctx, u) + ourAccount, err := c.db.GetAccountByUsernameDomain(ctx, u, "") if err != nil { 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 { return nil, fmt.Errorf("error creating transport for user %s: %s", username, err) } + return transport, nil }