diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 560fbc9f6..6f925e24f 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -40,6 +40,11 @@ type Caches struct { // the block []headerfilter.Filter cache. BlockHeaderFilters headerfilter.Cache + // TTL cache of statuses -> filterable text fields. + // To ensure up-to-date fields, cache is keyed as: + // `[status.ID][status.UpdatedAt.Unix()]` + StatusesFilterableFields *ttl.Cache[string, []string] + // Visibility provides access to the item visibility // cache. (used by the visibility filter). Visibility VisibilityCache @@ -47,11 +52,6 @@ type Caches struct { // Webfinger provides access to the webfinger URL cache. Webfinger *ttl.Cache[string, string] // TTL=24hr, sweep=5min - // TTL cache of statuses -> filterable text fields. - // To ensure up-to-date fields, cache is keyed as: - // `[status.ID][status.UpdatedAt.Unix()]` - StatusesFilterableFields *ttl.Cache[string, []string] - // prevent pass-by-value. _ nocopy } @@ -203,6 +203,15 @@ func (c *Caches) Sweep(threshold float64) { c.Visibility.Trim(threshold) } +func (c *Caches) initStatusesFilterableFields() { + c.StatusesFilterableFields = new(ttl.Cache[string, []string]) + c.StatusesFilterableFields.Init( + 0, + 512, + 1*time.Hour, + ) +} + func (c *Caches) initWebfinger() { // Calculate maximum cache size. cap := calculateCacheMax( @@ -219,12 +228,3 @@ func (c *Caches) initWebfinger() { 24*time.Hour, ) } - -func (c *Caches) initStatusesFilterableFields() { - c.StatusesFilterableFields = new(ttl.Cache[string, []string]) - c.StatusesFilterableFields.Init( - 0, - 512, - 1*time.Hour, - ) -} diff --git a/internal/federation/federatingdb/create.go b/internal/federation/federatingdb/create.go index 60232efe3..11030b16b 100644 --- a/internal/federation/federatingdb/create.go +++ b/internal/federation/federatingdb/create.go @@ -63,6 +63,10 @@ func (f *federatingDB) Create(ctx context.Context, asType vocab.Type) error { return nil } + // Cache entry for this create activity ID for later + // checks in the Exist() function if we see it again. + f.activityIDs.Set(ap.GetJSONLDId(asType).String(), struct{}{}) + switch name := asType.GetTypeName(); name { case ap.ActivityBlock: // BLOCK SOMETHING diff --git a/internal/federation/federatingdb/db.go b/internal/federation/federatingdb/db.go index ba10ed98b..230098073 100644 --- a/internal/federation/federatingdb/db.go +++ b/internal/federation/federatingdb/db.go @@ -21,6 +21,7 @@ "context" "net/url" + "codeberg.org/gruf/go-cache/v3/simple" "github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/gotosocial/internal/filter/interaction" @@ -61,6 +62,10 @@ type federatingDB struct { visFilter *visibility.Filter intFilter *interaction.Filter spamFilter *spam.Filter + + // tracks Activity IDs we have handled creates for, + // for use in the Exists() function during forwarding. + activityIDs simple.Cache[string, struct{}] } // New returns a DB that satisfies the pub.Database @@ -79,5 +84,6 @@ func New( intFilter: intFilter, spamFilter: spamFilter, } + fdb.activityIDs.Init(0, 2048) return &fdb } diff --git a/internal/federation/federatingdb/exists.go b/internal/federation/federatingdb/exists.go index abac9960e..ec996f72f 100644 --- a/internal/federation/federatingdb/exists.go +++ b/internal/federation/federatingdb/exists.go @@ -22,12 +22,8 @@ "net/url" ) -// Exists returns true if the database has an entry for the specified -// id. It may not be owned by this application instance. -// -// The library makes this call only after acquiring a lock first. -// -// Implementation note: this just straight up isn't implemented, and doesn't *really* need to be either. +// Exists is an implementation of pub.Database{}.Exists(), optimized specifically for +// the only usecase in which go-fed/activity/pub actually calls it. Do not use otherwise! func (f *federatingDB) Exists(ctx context.Context, id *url.URL) (exists bool, err error) { - return false, nil + return f.activityIDs.Has(id.String()), nil } diff --git a/internal/federation/federator.go b/internal/federation/federator.go index 4e11c7d4d..b6f54906b 100644 --- a/internal/federation/federator.go +++ b/internal/federation/federator.go @@ -33,7 +33,7 @@ var _ interface { pub.CommonBehavior pub.FederatingProtocol -} = &Federator{} +} = (*Federator)(nil) type Federator struct { db db.DB diff --git a/internal/federation/transport.go b/internal/federation/transport.go index b6f7a46c8..bab89eafc 100644 --- a/internal/federation/transport.go +++ b/internal/federation/transport.go @@ -49,7 +49,7 @@ // Note that the library will not maintain a long-lived pointer to the // returned Transport so that any private credentials are able to be // garbage collected. -func (f *Federator) NewTransport(ctx context.Context, actorBoxIRI *url.URL, gofedAgent string) (pub.Transport, error) { +func (f *Federator) NewTransport(ctx context.Context, actorBoxIRI *url.URL, _ string) (pub.Transport, error) { var username string var err error