summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar kim <grufwub@gmail.com>2025-10-13 14:03:17 +0200
committerLibravatar tobi <tobi.smethurst@protonmail.com>2025-10-17 15:32:50 +0200
commit3a5119b5ff2c8f6ecb02d4054002b3845ca05e9c (patch)
tree39a16e66ea60f6bd46a3d75e6da0c73b2705c118
parent[performance] add benchmarks for native Go imaging code, small tweaks to redu... (diff)
downloadgotosocial-3a5119b5ff2c8f6ecb02d4054002b3845ca05e9c.tar.xz
[bugfix] repeated posts on timeline endpoints (#4494)
- updates the go-structr library to add support for getting the current HEAD and TAIL primary key values, which allows us to not insert statuses if they're older than the current oldest timeline item - ensures the nextPg parameters get updated after loading from the cache before then performing a database query closes: https://codeberg.org/superseriousbusiness/gotosocial/issues/4491 Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4494 Co-authored-by: kim <grufwub@gmail.com> Co-committed-by: kim <grufwub@gmail.com>
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--internal/cache/timeline/status.go10
-rw-r--r--vendor/codeberg.org/gruf/go-structr/timeline.go33
-rw-r--r--vendor/modules.txt2
5 files changed, 47 insertions, 4 deletions
diff --git a/go.mod b/go.mod
index 9d3d8c988..1416b1786 100644
--- a/go.mod
+++ b/go.mod
@@ -31,7 +31,7 @@ require (
codeberg.org/gruf/go-sched v1.2.4
codeberg.org/gruf/go-split v1.2.0
codeberg.org/gruf/go-storage v0.3.1
- codeberg.org/gruf/go-structr v0.9.12
+ codeberg.org/gruf/go-structr v0.9.13
github.com/DmitriyVTitov/size v1.5.0
github.com/KimMachineGun/automemlimit v0.7.4
github.com/SherClockHolmes/webpush-go v1.4.0
diff --git a/go.sum b/go.sum
index f68de3494..6623fc830 100644
--- a/go.sum
+++ b/go.sum
@@ -54,8 +54,8 @@ codeberg.org/gruf/go-split v1.2.0 h1:PmzL23nVEVHm8VxjsJmv4m4wGQz2bGgQw52dgSSj65c
codeberg.org/gruf/go-split v1.2.0/go.mod h1:0rejWJpqvOoFAd7nwm5tIXYKaAqjtFGOXmTqQV+VO38=
codeberg.org/gruf/go-storage v0.3.1 h1:g66UIM/xXnEk9ejT+W0T9s/PODBZhXa/8ajzeY/MELI=
codeberg.org/gruf/go-storage v0.3.1/go.mod h1:r43n/zi7YGOCl2iSl7AMI27D1zcWS65Bi2+5xDzypeo=
-codeberg.org/gruf/go-structr v0.9.12 h1:yMopvexnuKgZme9WgvIhrJaAuAjfper/x38xsVuJOOo=
-codeberg.org/gruf/go-structr v0.9.12/go.mod h1:sP2ZSjM5X5XKlxuhAbTKuVQm9DWbHsrQRuTl3MUwbHw=
+codeberg.org/gruf/go-structr v0.9.13 h1:tTAR30OnSKrcvBomlGZdwE2nE+cfWhkX8UhX0GTAbMo=
+codeberg.org/gruf/go-structr v0.9.13/go.mod h1:sP2ZSjM5X5XKlxuhAbTKuVQm9DWbHsrQRuTl3MUwbHw=
codeberg.org/gruf/go-xunsafe v0.0.0-20250809104800-512a9df57d73 h1:pRaOwIOS1WSZoPCAvE0H1zpv+D4gF37OVppybffqdI8=
codeberg.org/gruf/go-xunsafe v0.0.0-20250809104800-512a9df57d73/go.mod h1:9wkq+dmHjUhB/0ZxDUWAwsWuXwwGyx5N1dDCB9hpWs8=
codeberg.org/superseriousbusiness/go-swagger v0.32.3-gts-go1.23-fix h1:k76/Th+bruqU/d+dB0Ru466ctTF2aVjKpisy/471ILE=
diff --git a/internal/cache/timeline/status.go b/internal/cache/timeline/status.go
index 7e6d3aa27..9e3957ac2 100644
--- a/internal/cache/timeline/status.go
+++ b/internal/cache/timeline/status.go
@@ -387,6 +387,9 @@ func (t *StatusTimeline) Load(
return nil, "", "", gtserror.Newf("error loading statuses: %w", err)
}
+ // Update nextPg cursor parameter for database query.
+ nextPageParams(nextPg, metas[len(metas)-1].ID, order)
+
// Prepare frontend API models for
// the cached statuses. For now this
// also does its own extra filtering.
@@ -536,6 +539,13 @@ func (t *StatusTimeline) InsertOne(status *gtsmodel.Status, prepared *apimodel.S
return false
}
+ // If item is beyond end of the
+ // timeline, don't bother adding.
+ if tailID := t.cache.Tail(); //
+ tailID == nil || status.ID < *tailID {
+ return false
+ }
+
if status.BoostOfID != "" {
// Check through top $repeatBoostDepth number of items.
for i, value := range t.cache.RangeUnsafe(structr.Desc) {
diff --git a/vendor/codeberg.org/gruf/go-structr/timeline.go b/vendor/codeberg.org/gruf/go-structr/timeline.go
index 749ec862a..e738a8228 100644
--- a/vendor/codeberg.org/gruf/go-structr/timeline.go
+++ b/vendor/codeberg.org/gruf/go-structr/timeline.go
@@ -7,6 +7,7 @@ import (
"slices"
"strings"
"sync"
+ "sync/atomic"
"unsafe"
"codeberg.org/gruf/go-mempool"
@@ -83,6 +84,11 @@ type Timeline[StructType any, PK cmp.Ordered] struct {
// types by user defined sets of fields.
indices []Index
+ // atomically updated head
+ // / tail primary key values.
+ headPK unsafe.Pointer
+ tailPK unsafe.Pointer
+
// protective mutex, guards:
// - Timeline{}.*
// - Index{}.data
@@ -150,6 +156,16 @@ func (t *Timeline[T, PK]) Index(name string) *Index {
panic("unknown index: " + name)
}
+// Head returns the current head primary key.
+func (t *Timeline[T, PK]) Head() *PK {
+ return (*PK)(atomic.LoadPointer(&t.headPK))
+}
+
+// Tail returns the current tail primary key.
+func (t *Timeline[T, PK]) Tail() *PK {
+ return (*PK)(atomic.LoadPointer(&t.tailPK))
+}
+
// Select allows you to retrieve a slice of values, in order, from the timeline.
// This slice is defined by the minimum and maximum primary key parameters, up to
// a given length in size. The direction in which you select will determine which
@@ -570,6 +586,10 @@ func (t *Timeline[T, PK]) Trim(max int, dir Direction) {
bottom := t.list.tail
if bottom == nil {
+ // Zero head + tail primary keys.
+ atomic.StorePointer(&t.headPK, nil)
+ atomic.StorePointer(&t.tailPK, nil)
+
// reached
// end.
break
@@ -589,6 +609,10 @@ func (t *Timeline[T, PK]) Trim(max int, dir Direction) {
top := t.list.head
if top == nil {
+ // Zero head + tail primary keys.
+ atomic.StorePointer(&t.headPK, nil)
+ atomic.StorePointer(&t.tailPK, nil)
+
// reached
// end.
break
@@ -1034,6 +1058,15 @@ func (t *Timeline[T, PK]) store_one(last *list_elem, value value_with_pk[T, PK])
goto indexing
indexing:
+ // Set new head / tail
+ // primary key values.
+ switch last {
+ case t.list.head:
+ atomic.StorePointer(&t.headPK, value.kptr)
+ case t.list.tail:
+ atomic.StorePointer(&t.tailPK, value.kptr)
+ }
+
// Append already-extracted
// primary key to 0th index.
_ = idx0.add(key, i_item)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 10c10e1c2..3f8477520 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -293,7 +293,7 @@ codeberg.org/gruf/go-storage/disk
codeberg.org/gruf/go-storage/internal
codeberg.org/gruf/go-storage/memory
codeberg.org/gruf/go-storage/s3
-# codeberg.org/gruf/go-structr v0.9.12
+# codeberg.org/gruf/go-structr v0.9.13
## explicit; go 1.24.5
codeberg.org/gruf/go-structr
# codeberg.org/gruf/go-xunsafe v0.0.0-20250809104800-512a9df57d73