[performance] retry db queries on busy errors (#2025)

* catch SQLITE_BUSY errors, wrap bun.DB to use our own busy retrier, remove unnecessary db.Error type

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

* remove dead code

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

* remove more dead code, add missing error arguments

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

* update sqlite to use maxOpenConns()

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

* add uncommitted changes

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

* use direct calls-through for the ConnIface to make sure we don't double query hook

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

* expose underlying bun.DB better

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

* retry on the correct busy error

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

* use longer possible maxRetries for db retry-backoff

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

* remove the note regarding max-open-conns only applying to postgres

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

* improved code commenting

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

* remove unnecessary infof call (just use info)

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

* rename DBConn to WrappedDB to better follow sql package name conventions

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

* update test error string checks

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

* shush linter

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

* update backoff logic to be more transparent

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

---------

Signed-off-by: kim <grufwub@gmail.com>
This commit is contained in:
kim 2023-07-25 09:34:05 +01:00 committed by GitHub
commit 5f3e095717
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 1050 additions and 898 deletions

View file

@ -26,7 +26,7 @@ import (
// Relationship contains functions for getting or modifying the relationship between two accounts.
type Relationship interface {
// IsBlocked checks whether source account has a block in place against target.
IsBlocked(ctx context.Context, sourceAccountID string, targetAccountID string) (bool, Error)
IsBlocked(ctx context.Context, sourceAccountID string, targetAccountID string) (bool, error)
// IsEitherBlocked checks whether there is a block in place between either of account1 and account2.
IsEitherBlocked(ctx context.Context, accountID1 string, accountID2 string) (bool, error)
@ -53,7 +53,7 @@ type Relationship interface {
DeleteAccountBlocks(ctx context.Context, accountID string) error
// GetRelationship retrieves the relationship of the targetAccount to the requestingAccount.
GetRelationship(ctx context.Context, requestingAccount string, targetAccount string) (*gtsmodel.Relationship, Error)
GetRelationship(ctx context.Context, requestingAccount string, targetAccount string) (*gtsmodel.Relationship, error)
// GetFollowByID fetches follow with given ID from the database.
GetFollowByID(ctx context.Context, id string) (*gtsmodel.Follow, error)
@ -77,13 +77,13 @@ type Relationship interface {
GetFollowRequest(ctx context.Context, sourceAccountID string, targetAccountID string) (*gtsmodel.FollowRequest, error)
// IsFollowing returns true if sourceAccount follows target account, or an error if something goes wrong while finding out.
IsFollowing(ctx context.Context, sourceAccountID string, targetAccountID string) (bool, Error)
IsFollowing(ctx context.Context, sourceAccountID string, targetAccountID string) (bool, error)
// IsMutualFollowing returns true if account1 and account2 both follow each other, or an error if something goes wrong while finding out.
IsMutualFollowing(ctx context.Context, sourceAccountID string, targetAccountID string) (bool, Error)
IsMutualFollowing(ctx context.Context, sourceAccountID string, targetAccountID string) (bool, error)
// IsFollowRequested returns true if sourceAccount has requested to follow target account, or an error if something goes wrong while finding out.
IsFollowRequested(ctx context.Context, sourceAccountID string, targetAccountID string) (bool, Error)
IsFollowRequested(ctx context.Context, sourceAccountID string, targetAccountID string) (bool, error)
// PutFollow attempts to place the given account follow in the database.
PutFollow(ctx context.Context, follow *gtsmodel.Follow) error
@ -125,10 +125,10 @@ type Relationship interface {
// In other words, it should create the follow, and delete the existing follow request.
//
// It will return the newly created follow for further processing.
AcceptFollowRequest(ctx context.Context, originAccountID string, targetAccountID string) (*gtsmodel.Follow, Error)
AcceptFollowRequest(ctx context.Context, originAccountID string, targetAccountID string) (*gtsmodel.Follow, error)
// RejectFollowRequest fetches a follow request from the database, and then deletes it.
RejectFollowRequest(ctx context.Context, originAccountID string, targetAccountID string) Error
RejectFollowRequest(ctx context.Context, originAccountID string, targetAccountID string) error
// GetAccountFollows returns a slice of follows owned by the given accountID.
GetAccountFollows(ctx context.Context, accountID string) ([]*gtsmodel.Follow, error)