Skip to content

fix(peertube): advance the content discovery cursor past every video read - #266

Open
kevin9327 wants to merge 1 commit into
getopenpost:mainfrom
kevin9327:fix/peertube-discovery-cursor
Open

kevin9327 wants to merge 1 commit into
getopenpost:mainfrom
kevin9327:fix/peertube-discovery-cursor

Conversation

@kevin9327

@kevin9327 kevin9327 commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

PeerTube account content discovery could never finish a cycle once a channel had a video older than the discovery window. When that happened, the cycle got stuck on one cursor and new uploads were never discovered.

DiscoverAccountContent pages GET /api/v1/video-channels/{handle}/videos by offset (start). It computed the next offset as start + len(page.Items), which counts only the videos it kept. Videos filtered out for predating PublishedAfter, or dropped by normalization, still occupy their offsets in PeerTube's listing, so the next page started inside the page just read. At the window's lower bound nothing is kept, so the same cursor came back every time.

The fix:

  • advance the cursor by every video read: start + len(result.Data)
  • stop at the first video older than the window, since the listing is requested with sort=-publishedAt (newest first), the same way the Mastodon-compatible discovery stops at its lower bound

Motivation

What this does in the discovery job (internal/services/analytics/discovery.go) on today's main:

  • CyclePublishedAfter is always set: 90 days back for the initial cycle, and the previous cycle start for routine cycles.
  • A non-empty NextCursor makes the job continue from that cursor. A new cycle only starts once the cursor is empty.
  • The repeated page costs a read each time, until reserveDiscoveryReads hits the default ReadRequestsPerDay of 10 and defers to the next day. The next day it resumes from the same stuck cursor.

I reproduced this end to end, without committing the harness. I ran the real PeerTubeAdapter through ReconsiderAccountContentDiscovery and HandleJob, against a TLS fake channel of 3 videos with one older than 90 days. On main the requests went start=[0 2 2 2 2 2 2 2 2 2] and ended with cursor="2", failure="account_read_budget_exhausted" and initialCompleted=false. With this change it made a single request, cursor="", and initialCompleted=true, with both in-window videos stored.

PeerTube's side, at v8.3.0:

normalizeAccountContentVideo no longer takes the window. The window check moved into the loop, where it can end the page.

Testing

  • Backend tests pass (go test ./internal/platform/..., go test ./internal/services/analytics/...)
  • Frontend tests pass (bun run --filter @openpost/web test): no frontend change
  • Linting passes (go vet, gofmt, gofumpt, golangci-lint run ./internal/platform/...: 0 issues, same as main)
  • Manually tested: new TestPeerTubeAccountContentDiscoveryCursorReachesTheEnd drives discovery the way the job does, feeding each NextCursor back. The fake channel has 30 videos: the last three predate the window, and one video on the first page has no usable publish time. The test checks the offsets are 0 then 25 and that all 26 in-window videos are returned. It fails if the cursor doesn't reach the end within 5 pages. There was no PeerTube discovery test before.

Fails on unmodified main:

=== RUN   TestPeerTubeAccountContentDiscoveryCursorReachesTheEnd
    peertube_test.go:472:
        	Error:      	"5" is not less than "5"
        	Messages:   	discovery must reach the end of the channel instead of repeating a cursor; requested starts [0 24 27 27 27]
--- FAIL: TestPeerTubeAccountContentDiscoveryCursorReachesTheEnd (0.00s)

Passes with the fix. go test ./internal/platform/... and ./internal/services/analytics/... are ok, and go build -tags dev ./... is clean. go test -coverprofile shows every changed line runs under the new test. This PR and #265 edit different parts of peertube.go and peertube_test.go. git merge-tree merges them cleanly, and golangci-lint plus the PeerTube tests pass on the merged tree.

Checklist

  • My code follows the project's coding conventions
  • I have added tests that prove my fix is effective
  • I have updated documentation if needed: added changes/peertube-discovery-cursor.md
  • I have used Conventional Commits for my commit messages
  • I have checked that there are no other PRs open for the same issue/feature

Breaking Changes

  • Yes
  • No

Affected Components

  • Backend (Go)

Platform Impact

  • PeerTube

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed PeerTube account content discovery pagination to stop at the publication-date boundary.
    • Prevented repeated pagination through stale pages and duplicate cursor progression.
    • Improved discovery continuity so newer videos can be found without unnecessarily exhausting the daily read limit.
    • Excluded videos outside the configured publication window or without publication dates.

…read

DiscoverAccountContent pages the channel's videos by offset, but the
next offset was start plus the number of videos kept on the page. Videos
older than the discovery window, or dropped by normalization, did not
count, so the next page started inside the one just read. Once the
window's lower bound was reached no video was kept at all, and the
same cursor came back until the daily read budget ran out. The cycle
never finished, so newer uploads were never discovered.

Advance by every video read, and stop at the first video older than the
window, since the listing is sorted newest first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 59776f07-1282-4cc6-a497-1816e3e5cab4

📥 Commits

Reviewing files that changed from the base of the PR and between 542f87b and daf76df.

📒 Files selected for processing (3)
  • apps/server/internal/platform/peertube.go
  • apps/server/internal/platform/peertube_test.go
  • changes/peertube-discovery-cursor.md

Included review availability: Your plan provides up to 4 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

PeerTube account discovery now stops at videos older than the publication window and advances pagination by every video fetched. A test covers multi-page channels, filtering, cursor progression, and termination. A changelog entry documents the fix.

Changes

PeerTube discovery

Layer / File(s) Summary
Publication boundary and cursor handling
apps/server/internal/platform/peertube.go
The listing loop stops when it reaches an older video. The cursor advances by all fetched videos, and normalizeAccountContentVideo no longer performs publication-window filtering.
Pagination regression coverage
apps/server/internal/platform/peertube_test.go, changes/peertube-discovery-cursor.md
The test validates multi-page pagination, filtering, cursor advancement, and termination. The changelog records the fix.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~15 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: rodrgds

Merge Risk: ⚪ Minimal · up to daf76

The pagination change handles invalid publication timestamps without prematurely stopping discovery, and no actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: advancing the PeerTube content discovery cursor by every video read to prevent repeated pagination cursors.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant