diff options
author | 2025-01-27 19:22:15 +0100 | |
---|---|---|
committer | 2025-01-27 19:22:15 +0100 | |
commit | 65fb8abd423fd449211019df6f1425957b7d1b92 (patch) | |
tree | 13219514e0a774520b0fd84c85d294c02370f5d6 /internal | |
parent | [chore] skip `trusted-proxies` warning if ip excepted from rate limiting (#3699) (diff) | |
download | gotosocial-65fb8abd423fd449211019df6f1425957b7d1b92.tar.xz |
[feature] Implement `deliveryRecipientPreSort` to prioritize delivery to mentioned accounts (#3668)
* weeeeenus
* update to latest activity
* update to use latest release tag of superseriousbusiness/activity
---------
Co-authored-by: kim <grufwub@gmail.com>
Diffstat (limited to 'internal')
-rw-r--r-- | internal/federation/federatingactor.go | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/internal/federation/federatingactor.go b/internal/federation/federatingactor.go index 83cee4b04..6ea737eb0 100644 --- a/internal/federation/federatingactor.go +++ b/internal/federation/federatingactor.go @@ -23,6 +23,7 @@ import ( "fmt" "net/http" "net/url" + "slices" errorsv2 "codeberg.org/gruf/go-errors/v2" "codeberg.org/gruf/go-kv" @@ -30,9 +31,11 @@ import ( "github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/gotosocial/internal/ap" apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" + "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/uris" ) // federatingActor wraps the pub.FederatingActor @@ -42,10 +45,63 @@ type federatingActor struct { wrapped pub.FederatingActor } +func deliveryRecipientPreSort(actorAndCollectionIRIs []*url.URL) []*url.URL { + var ( + thisHost = config.GetHost() + thisAcctDomain = config.GetAccountDomain() + ) + + slices.SortFunc( + actorAndCollectionIRIs, + func(a *url.URL, b *url.URL) int { + // We want to sort by putting more specific actor URIs *before* collection URIs. + // Since the only collection URIs we ever address are our own followers URIs, we + // can just use host and regexes to identify these collections, and shove them + // to the back of the slice. This ensures that directly addressed (ie., mentioned) + // accounts get delivery-attempted *first*, and then delivery attempts move on to + // followers of the author. This should have the effect of making conversation + /// threads feel more snappy, as replies will be sent quicker to participants. + var ( + aIsFollowers = (a.Host == thisHost || a.Host == thisAcctDomain) && uris.IsFollowersPath(a) + bIsFollowers = (b.Host == thisHost || b.Host == thisAcctDomain) && uris.IsFollowersPath(b) + ) + + switch { + case aIsFollowers == bIsFollowers: + // Both followers URIs or + // both not followers URIs, + // order doesn't matter. + return 0 + + case aIsFollowers: + // a is followers + // URI, b is not. + // + // Sort b before a. + return 1 + + default: + // b is followers + // URI, a is not. + // + // Sort a before b. + return -1 + } + }, + ) + + return actorAndCollectionIRIs +} + // newFederatingActor returns a federatingActor. func newFederatingActor(c pub.CommonBehavior, s2s pub.FederatingProtocol, db pub.Database, clock pub.Clock) pub.FederatingActor { sideEffectActor := pub.NewSideEffectActor(c, s2s, nil, db, clock) - sideEffectActor.Serialize = ap.Serialize // hook in our own custom Serialize function + + // Hook in our own custom Serialize function. + sideEffectActor.Serialize = ap.Serialize + + // Hook in our own custom recipient pre-sort function. + sideEffectActor.DeliveryRecipientPreSort = deliveryRecipientPreSort return &federatingActor{ sideEffectActor: sideEffectActor, |