Skip to content

feat: add peer and tracker management - #258

Merged
artrixdotdev merged 3 commits into
mainfrom
feat/add-peer-tracker-management-api
Aug 3, 2026
Merged

feat: add peer and tracker management#258
artrixdotdev merged 3 commits into
mainfrom
feat/add-peer-tracker-management-api

Conversation

@artrixdotdev

@artrixdotdev artrixdotdev commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • expose typed Torrent APIs to add and disconnect peers, add and remove trackers, and queue per-tracker or torrent-wide reannounces
  • keep Torrent as the sole command surface while peer and tracker handles provide stable identities and live status/event access
  • return typed duplicate, missing, unsupported-protocol, and actor-delivery errors instead of silently dropping frontend operations
  • cover peer and tracker management through deterministic local peer and HTTP tracker fixtures
  • use a portable CI build target so shared Rust cache artifacts work across GitHub runner CPUs

API boundary

Peer connection succeeds after the handshake and swarm registration boundary. Tracker registration and announce commands follow the existing actor model: command delivery is guaranteed, while tracker initialization and network responses remain asynchronous and observable through TrackerHandle views and listeners. Tracker removal immediately updates the authoritative registry and live terminal state; its stopped announce is best-effort.

The implementation reuses the existing peer removal path, tracker actor construction, live scope registry, and tracker status/event projection. Inline comments document only the non-obvious handshake, shared tracker-registration, and shutdown flows.

Closes #226

Validation

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo clippy -p libtortillas --no-default-features --all-targets -- -D warnings
  • cargo nextest run --workspace --all-features — 194 passed, 9 skipped
  • cargo nextest run --workspace --all-features --run-ignored only — 9 passed
  • cargo test -p libtortillas --all-features --doc — 28 passed, 6 ignored
  • RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps
  • GitHub Actions build_and_test and lint

Summary by CodeRabbit

  • New Features

    • Added APIs to add, disconnect, and manage torrent peers.
    • Added tracker management, including adding, removing, and reannouncing trackers.
    • Added force reannounce support with success reporting.
    • Exposed tracker information through the application interface.
  • Bug Fixes

    • Improved peer connection handling with clearer errors and connection timeouts.
    • Tracker setup failures are now handled individually without preventing torrent startup.
    • Added validation for duplicate or missing peers and trackers.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8607518e-a433-4149-8dd6-cf857181d2fd

📥 Commits

Reviewing files that changed from the base of the PR and between d747efc and 7e629c1.

📒 Files selected for processing (5)
  • .github/workflows/checks.yml
  • crates/libtortillas/src/lib.rs
  • crates/libtortillas/src/torrent/handle.rs
  • crates/libtortillas/src/torrent/messages.rs
  • crates/libtortillas/src/torrent/swarm.rs
💤 Files with no reviewable changes (1)
  • .github/workflows/checks.yml
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/libtortillas/src/lib.rs
  • crates/libtortillas/src/torrent/handle.rs
  • crates/libtortillas/src/torrent/swarm.rs
  • crates/libtortillas/src/torrent/messages.rs

Walkthrough

Torrent live APIs now support manual peer management and tracker lifecycle controls. Actor message flows return typed results, tracker registration is supervised and protocol-checked, live hub lookups resolve tracker relationships, and tests cover peer and tracker operations.

Changes

Peer and tracker lifecycle

Layer / File(s) Summary
Lifecycle contracts and lookup wiring
crates/libtortillas/src/errors.rs, crates/libtortillas/src/torrent/mod.rs, crates/libtortillas/src/live/hub.rs, crates/libtortillas/src/facade.rs
Typed peer and tracker errors, feature-gated result aliases, tracker lookup helpers, and the public Tracker facade export were added.
Peer connection and disconnection flow
crates/libtortillas/src/torrent/swarm.rs, crates/libtortillas/src/torrent/messages.rs, crates/libtortillas/src/torrent/handle.rs, crates/libtortillas/src/torrent/actor.rs
Peer handshakes run asynchronously. Manual additions return delegated results. Invalid and duplicate peers return errors. Peers can be disconnected explicitly.
Tracker registration and control flow
crates/libtortillas/src/torrent/swarm.rs, crates/libtortillas/src/torrent/actor.rs, crates/libtortillas/src/torrent/messages.rs, crates/libtortillas/src/torrent/handle.rs
Tracker registration rejects unsupported protocols, creates supervised tracker actors, and exposes add, remove, reannounce, and force-reannounce operations.
Runtime initialization and lifecycle validation
crates/libtortillas/src/torrent/actor.rs, crates/libtortillas/src/torrent/piece_flow.rs, crates/libtortillas/src/lib.rs, crates/libtortillas/src/torrent/handle.rs, .github/workflows/checks.yml
Actor fixtures initialize primary_addr. Startup skips tracker registration failures. Local peer connections remain active. Live lifecycle tests and workflow settings were updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: enhancement, med prio, refactor

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding peer and tracker management APIs.
Linked Issues check ✅ Passed The changes add public peer and tracker management APIs, typed errors, handle access, and deterministic lifecycle and reannounce tests required by issue #226.
Out of Scope Changes check ✅ Passed The workflow, lifecycle, registry, and test-helper changes support portability, reliable actor behavior, and deterministic validation for the requested APIs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-peer-tracker-management-api

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.

@coderabbitai coderabbitai Bot added enhancement New feature or request med prio Medium Priority refactor Neither fixes a bug nor adds a feature labels Jul 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
crates/libtortillas/src/torrent/messages.rs (1)

249-271: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

tell(...).await per tracker can stall the torrent actor.

force_reannounce runs inside the torrent actor's handler and awaits each tracker's bounded mailbox sequentially, so one saturated tracker mailbox blocks the whole torrent loop (and every other command behind it). The sibling broadcast paths already use for_each_concurrent or try_send for this reason. Consider try_send (counting refusals as failures) or a concurrent send bounded by tracker_broadcast_concurrency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/libtortillas/src/torrent/messages.rs` around lines 249 - 271, The
force_reannounce handler must not await each tracker mailbox sequentially.
Update force_reannounce to use the existing non-blocking or bounded-concurrency
tracker broadcast pattern, such as try_send or tracker_broadcast_concurrency,
while preserving queued-counting and first-error reporting for failed sends.
crates/libtortillas/src/torrent/handle.rs (1)

271-279: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Unbounded listener.recv() in tests.

Both new tests await listener.recv() without a timeout(...) in a couple of places (here and in the tracker test's first recvs they do use timeouts). An unmet event hangs the test until the harness-wide limit instead of failing fast. Wrapping this one in timeout keeps the suite diagnosable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/libtortillas/src/torrent/handle.rs` around lines 271 - 279, Wrap the
await on listener.recv() in the disconnect-peer test with the existing timeout
mechanism, preserving the current Disconnected event assertion while making a
missing event fail promptly; apply the same bounded receive to the other new
unbounded listener.recv() calls in the tracker test.
crates/libtortillas/src/lib.rs (1)

570-575: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document why the fixture never returns.

std::future::pending() deliberately keeps the connection open so the peer under test doesn't observe an immediate EOF after the scripted messages; cleanup relies on LocalPeer::drop aborting the accept task and, with it, the JoinSet. That contract is non-obvious — worth a one-line comment so a future reader doesn't "fix" it back to Ok(()).

📝 Suggested comment
+      // Keep the connection open so the client does not see an EOF right after
+      // the scripted messages. `LocalPeer::drop` aborts this task.
       std::future::pending().await
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/libtortillas/src/lib.rs` around lines 570 - 575, Add a concise comment
immediately before std::future::pending().await in the fixture’s message-stream
handling to document that it intentionally keeps the connection open, preventing
EOF until LocalPeer::drop aborts the accept task and its JoinSet. Do not change
the existing control flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/libtortillas/src/torrent/swarm.rs`:
- Around line 46-91: Bound the spawned connection future in the add-peer flow
around PeerStream::connect, send_handshake, and recv_handshake_message using the
configured peer-handshake timeout. Convert expiration into the established typed
TorrentError timeout variant so the awaited add_peer request and discovery task
terminate predictably, while preserving existing handshake and registration
errors.

---

Nitpick comments:
In `@crates/libtortillas/src/lib.rs`:
- Around line 570-575: Add a concise comment immediately before
std::future::pending().await in the fixture’s message-stream handling to
document that it intentionally keeps the connection open, preventing EOF until
LocalPeer::drop aborts the accept task and its JoinSet. Do not change the
existing control flow.

In `@crates/libtortillas/src/torrent/handle.rs`:
- Around line 271-279: Wrap the await on listener.recv() in the disconnect-peer
test with the existing timeout mechanism, preserving the current Disconnected
event assertion while making a missing event fail promptly; apply the same
bounded receive to the other new unbounded listener.recv() calls in the tracker
test.

In `@crates/libtortillas/src/torrent/messages.rs`:
- Around line 249-271: The force_reannounce handler must not await each tracker
mailbox sequentially. Update force_reannounce to use the existing non-blocking
or bounded-concurrency tracker broadcast pattern, such as try_send or
tracker_broadcast_concurrency, while preserving queued-counting and first-error
reporting for failed sends.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 688a3e94-4158-421e-972b-63eb0954e6fe

📥 Commits

Reviewing files that changed from the base of the PR and between ca568eb and d747efc.

📒 Files selected for processing (10)
  • crates/libtortillas/src/errors.rs
  • crates/libtortillas/src/facade.rs
  • crates/libtortillas/src/lib.rs
  • crates/libtortillas/src/live/hub.rs
  • crates/libtortillas/src/torrent/actor.rs
  • crates/libtortillas/src/torrent/handle.rs
  • crates/libtortillas/src/torrent/messages.rs
  • crates/libtortillas/src/torrent/mod.rs
  • crates/libtortillas/src/torrent/piece_flow.rs
  • crates/libtortillas/src/torrent/swarm.rs

Comment thread crates/libtortillas/src/torrent/swarm.rs
- Prevent tracker announcements from blocking the torrent actor
- Enforce incoming peer handshake timeouts
- Stabilize peer disconnect test timing
@artrixdotdev
artrixdotdev merged commit a1e0e26 into main Aug 3, 2026
3 checks passed
@artrixdotdev
artrixdotdev deleted the feat/add-peer-tracker-management-api branch August 3, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request med prio Medium Priority refactor Neither fixes a bug nor adds a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add public peer and tracker management APIs

1 participant