mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature/performance] Fail fast when doing remote transport calls inside incoming request contexts (#1119)
* [feature/performance] Fail fast when doing remote transport calls inside incoming request contexts * [chore] Reduce outgoing request timeout to 15s * log error messages when fastfailing * use context.Value() instead of wrapped context, wrap error with fastfail instead of extra log entry * add fast-fail context key test Signed-off-by: kim <grufwub@gmail.com> Co-authored-by: kim <grufwub@gmail.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
)
|
||||
|
||||
func (p *processor) Get(ctx context.Context, requestingAccount *gtsmodel.Account, targetAccountID string) (*apimodel.Account, gtserror.WithCode) {
|
||||
@@ -93,7 +94,7 @@ func (p *processor) getAccountFor(ctx context.Context, requestingAccount *gtsmod
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error parsing url %s: %s", targetAccount.URI, err))
|
||||
}
|
||||
|
||||
a, err := p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
a, err := p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: requestingAccount.Username,
|
||||
RemoteAccountID: targetAccountURI,
|
||||
RemoteAccountHost: targetAccount.Domain,
|
||||
|
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
)
|
||||
|
||||
func (p *processor) GetFollowers(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
|
||||
@@ -41,7 +42,7 @@ func (p *processor) GetFollowers(ctx context.Context, requestedUsername string,
|
||||
return nil, errWithCode
|
||||
}
|
||||
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: requestedUsername,
|
||||
RemoteAccountID: requestingAccountURI,
|
||||
})
|
||||
|
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
)
|
||||
|
||||
func (p *processor) GetFollowing(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
|
||||
@@ -41,7 +42,7 @@ func (p *processor) GetFollowing(ctx context.Context, requestedUsername string,
|
||||
return nil, errWithCode
|
||||
}
|
||||
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: requestedUsername,
|
||||
RemoteAccountID: requestingAccountURI,
|
||||
})
|
||||
|
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
)
|
||||
|
||||
func (p *processor) GetOutbox(ctx context.Context, requestedUsername string, page bool, maxID string, minID string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
|
||||
@@ -42,7 +43,7 @@ func (p *processor) GetOutbox(ctx context.Context, requestedUsername string, pag
|
||||
return nil, errWithCode
|
||||
}
|
||||
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: requestedUsername,
|
||||
RemoteAccountID: requestingAccountURI,
|
||||
})
|
||||
|
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
)
|
||||
|
||||
func (p *processor) GetStatus(ctx context.Context, requestedUsername string, requestedStatusID string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
|
||||
@@ -41,7 +42,7 @@ func (p *processor) GetStatus(ctx context.Context, requestedUsername string, req
|
||||
return nil, errWithCode
|
||||
}
|
||||
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: requestedUsername,
|
||||
RemoteAccountID: requestingAccountURI,
|
||||
})
|
||||
|
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
)
|
||||
|
||||
func (p *processor) GetStatusReplies(ctx context.Context, requestedUsername string, requestedStatusID string, page bool, onlyOtherAccounts bool, minID string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
|
||||
@@ -43,7 +44,7 @@ func (p *processor) GetStatusReplies(ctx context.Context, requestedUsername stri
|
||||
return nil, errWithCode
|
||||
}
|
||||
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: requestedUsername,
|
||||
RemoteAccountID: requestingAccountURI,
|
||||
})
|
||||
|
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/uris"
|
||||
)
|
||||
|
||||
@@ -53,7 +54,7 @@ func (p *processor) GetUser(ctx context.Context, requestedUsername string, reque
|
||||
|
||||
// if we're not already handshaking/dereferencing a remote account, dereference it now
|
||||
if !p.federator.Handshaking(ctx, requestedUsername, requestingAccountURI) {
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
requestingAccount, err := p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: requestedUsername,
|
||||
RemoteAccountID: requestingAccountURI,
|
||||
})
|
||||
|
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/log"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/uris"
|
||||
)
|
||||
|
||||
@@ -141,11 +142,11 @@ func (p *processor) getAttachmentContent(ctx context.Context, requestingAccount
|
||||
// large version and derive a thumbnail from it, so use the normal recaching procedure: fetch the media,
|
||||
// process it, then return the thumbnail data
|
||||
data = func(innerCtx context.Context) (io.ReadCloser, int64, error) {
|
||||
transport, err := p.transportController.NewTransportForUsername(innerCtx, requestingUsername)
|
||||
t, err := p.transportController.NewTransportForUsername(innerCtx, requestingUsername)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return transport.DereferenceMedia(innerCtx, remoteMediaIRI)
|
||||
return t.DereferenceMedia(transport.WithFastfail(innerCtx), remoteMediaIRI)
|
||||
}
|
||||
} else {
|
||||
// if it's the full-sized version being requested, we can cheat a bit by streaming data to the user as
|
||||
@@ -172,12 +173,12 @@ func (p *processor) getAttachmentContent(ctx context.Context, requestingAccount
|
||||
attachmentContent.Content = io.NopCloser(bufferedReader)
|
||||
|
||||
data = func(innerCtx context.Context) (io.ReadCloser, int64, error) {
|
||||
transport, err := p.transportController.NewTransportForUsername(innerCtx, requestingUsername)
|
||||
t, err := p.transportController.NewTransportForUsername(innerCtx, requestingUsername)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
readCloser, fileSize, err := transport.DereferenceMedia(innerCtx, remoteMediaIRI)
|
||||
readCloser, fileSize, err := t.DereferenceMedia(transport.WithFastfail(innerCtx), remoteMediaIRI)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/log"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/util"
|
||||
)
|
||||
|
||||
@@ -161,13 +162,13 @@ func (p *processor) searchStatusByURI(ctx context.Context, authed *oauth.Auth, u
|
||||
|
||||
if resolve {
|
||||
// This is a non-local status and we're allowed to resolve, so dereference it
|
||||
status, statusable, err := p.federator.GetRemoteStatus(ctx, authed.Account.Username, uri, true, true)
|
||||
status, statusable, err := p.federator.GetRemoteStatus(transport.WithFastfail(ctx), authed.Account.Username, uri, true, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("searchStatusByURI: error fetching remote status %q: %v", uriStr, err)
|
||||
}
|
||||
|
||||
// Attempt to dereference the status thread while we are here
|
||||
p.federator.DereferenceRemoteThread(ctx, authed.Account.Username, uri, status, statusable)
|
||||
p.federator.DereferenceRemoteThread(transport.WithFastfail(ctx), authed.Account.Username, uri, status, statusable)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
@@ -190,7 +191,7 @@ func (p *processor) searchAccountByURI(ctx context.Context, authed *oauth.Auth,
|
||||
}
|
||||
|
||||
// we don't have it yet, try to find it remotely
|
||||
return p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
return p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: authed.Account.Username,
|
||||
RemoteAccountID: uri,
|
||||
Blocking: true,
|
||||
@@ -209,7 +210,7 @@ func (p *processor) searchAccountByMention(ctx context.Context, authed *oauth.Au
|
||||
}
|
||||
|
||||
// we don't have it yet, try to find it remotely
|
||||
return p.federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
return p.federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: authed.Account.Username,
|
||||
RemoteAccountUsername: username,
|
||||
RemoteAccountHost: domain,
|
||||
|
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/id"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/util"
|
||||
)
|
||||
|
||||
@@ -56,7 +57,7 @@ func GetParseMentionFunc(dbConn db.DB, federator federation.Federator) gtsmodel.
|
||||
if originAccount.Domain == "" {
|
||||
requestingUsername = originAccount.Username
|
||||
}
|
||||
remoteAccount, err := federator.GetRemoteAccount(ctx, dereferencing.GetRemoteAccountParams{
|
||||
remoteAccount, err := federator.GetRemoteAccount(transport.WithFastfail(ctx), dereferencing.GetRemoteAccountParams{
|
||||
RequestingUsername: requestingUsername,
|
||||
RemoteAccountUsername: username,
|
||||
RemoteAccountHost: domain,
|
||||
|
Reference in New Issue
Block a user