Skip to content

perf: reduce memory usage - #256

Merged
artrixdotdev merged 10 commits into
mainfrom
perf/reduce-memory-usage
Jul 27, 2026
Merged

perf: reduce memory usage#256
artrixdotdev merged 10 commits into
mainfrom
perf/reduce-memory-usage

Conversation

@artrixdotdev

@artrixdotdev artrixdotdev commented Jul 27, 2026

Copy link
Copy Markdown
Owner

No description provided.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@artrixdotdev, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 12 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8b45ed2d-d2fa-457d-8894-de8a44dab023

📥 Commits

Reviewing files that changed from the base of the PR and between 16ef5a5 and 52ef8d2.

📒 Files selected for processing (1)
  • crates/libtortillas/src/pieces/piece_scheduler.rs

Walkthrough

The PR refactors peer message encoding and stream I/O, changes handshake info hashes from Arc to direct values, caches torrent info hashes, improves tracker and piece handling, updates scheduling and live logging, and adds a local peer-transfer example.

Changes

Peer protocol transport

Layer / File(s) Summary
Message encoding and handshake contracts
crates/libtortillas/src/protocol/messages.rs
Peer messages use split piece headers and payloads, while handshake info hashes are stored directly as Hash<20>.
Peer stream framing and vectored writes
crates/libtortillas/src/protocol/stream.rs
Peer send/receive traits return futures, framing is handled explicitly, payload sizes are validated, and piece messages use vectored writes.
Handshake integration and callers
crates/libtortillas/src/engine/messages.rs, crates/libtortillas/src/lib.rs, crates/libtortillas/src/torrent/swarm.rs
Connection setup, validation, routing, and tests pass InfoHash values directly.

Torrent and tracker operations

Layer / File(s) Summary
Cached torrent identity and tracker setup
crates/libtortillas/src/torrent/actor.rs, crates/libtortillas/src/torrent/piece_flow.rs
TorrentActor caches its info hash and skips websocket tracker actors during startup.
Tracker and piece storage paths
crates/libtortillas/src/metainfo/file.rs, crates/libtortillas/src/pieces/piece_store.rs, crates/libtortillas/src/tracker/http.rs
Announce lists deduplicate trackers, piece files are read once before blocking validation, and HTTP trackers reuse a client.

Piece scheduling and live state

Layer / File(s) Summary
Piece request tracking and cursor scheduling
crates/libtortillas/src/pieces/piece_scheduler.rs
In-flight blocks use per-piece slots with per-peer counters and rotating request cursors.
Conditional live publication
crates/libtortillas/src/peer/actor.rs, crates/libtortillas/src/tracker/model.rs
Live state publication is limited to selected peer messages, and tracker methods compile without the live feature.

Examples and supporting updates

Layer / File(s) Summary
Local peer transfer example
crates/libtortillas/examples/peer_transfer.rs
A Tokio example transfers ordered pieces over a local TCP connection, validates them, and logs throughput.
Throttled live metrics logging
crates/libtortillas/examples/live.rs
Torrent metrics logs are throttled and other engine events receive generic logging.
Fixtures, tests, and documentation support
crates/libtortillas/src/lib.rs, crates/libtortillas/src/engine/messages.rs
Test fixtures, handshake setup, and documentation formatting were updated.

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

Sequence Diagram(s)

sequenceDiagram
  participant PeerTransfer
  participant PeerStream
  participant PeerMessages
  participant TCP
  PeerTransfer->>PeerMessages: encode Piece messages
  PeerMessages-->>PeerStream: return header and block
  PeerStream->>TCP: write vectored frame
  TCP-->>PeerStream: deliver bytes
  PeerStream-->>PeerTransfer: receive and validate Piece
Loading

Possibly related PRs

Suggested labels: enhancement, refactor

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. 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.
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.
Title check ✅ Passed The title matches the PR’s main performance theme and accurately reflects the memory-reduction focus of the changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/reduce-memory-usage

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 refactor Neither fixes a bug nor adds a feature labels Jul 27, 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: 3

🤖 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/examples/peer_transfer.rs`:
- Around line 25-35: Update the PeerMessages::Piece validation in the
stream.recv loop to verify every byte in block matches the expected 0xa5 value,
in addition to checking the index and BLOCK_LENGTH; retain the existing
unexpected-message error path for any mismatch.

In `@crates/libtortillas/src/protocol/stream.rs`:
- Around line 104-113: Bound the attacker-controlled frame length before
allocation in the stream parsing flow around the length check and
BytesMut::with_capacity. Add a module-level MAX_FRAME_PAYLOAD_LENGTH constant
sized for legitimate piece and extended-metadata messages, reject nonzero
lengths exceeding it, and preserve KeepAlive handling for length == 0.

In `@crates/libtortillas/src/torrent/actor.rs`:
- Around line 766-770: Update the websocket-tracker warning in the tracker
handling flow to log tracker.redacted_endpoint() instead of tracker.uri(),
preserving the existing warning message and match condition.
🪄 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: f3dcb162-e43e-4157-a0af-babca148375a

📥 Commits

Reviewing files that changed from the base of the PR and between 5df24ca and 8ee5a79.

📒 Files selected for processing (11)
  • crates/libtortillas/examples/peer_transfer.rs
  • crates/libtortillas/src/engine/messages.rs
  • crates/libtortillas/src/lib.rs
  • crates/libtortillas/src/metainfo/file.rs
  • crates/libtortillas/src/pieces/piece_store.rs
  • crates/libtortillas/src/protocol/messages.rs
  • crates/libtortillas/src/protocol/stream.rs
  • crates/libtortillas/src/torrent/actor.rs
  • crates/libtortillas/src/torrent/piece_flow.rs
  • crates/libtortillas/src/torrent/swarm.rs
  • crates/libtortillas/src/tracker/http.rs

Comment thread crates/libtortillas/examples/peer_transfer.rs
Comment thread crates/libtortillas/src/protocol/stream.rs
Comment thread crates/libtortillas/src/torrent/actor.rs

@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: 2

🧹 Nitpick comments (1)
crates/libtortillas/src/peer/actor.rs (1)

755-761: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add periodic or live-sample publishing for peer transfer rates.

When incoming PeerMessages::Piece is handled without publishing, PeerActor::handle only publishes on state-changing control messages. last_rate_sample also only gets refreshed in existing publish paths, so the live peer view can carry stale metrics.transfer.samples, metrics.transfer.rates, and consequently stale download rate/progress between non-piece messages.

🤖 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/peer/actor.rs` around lines 755 - 761, Update
PeerActor::handle so incoming PeerMessages::Piece messages periodically publish
live transfer samples even when no state-changing publication occurs. Refresh
last_rate_sample through the existing rate-sampling path before publishing,
ensuring the live PeerView contains current metrics.transfer.samples,
metrics.transfer.rates, download rate, and progress. Preserve existing publish
behavior and gate the added work consistently with the live feature and
publication settings.
🤖 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/examples/live.rs`:
- Around line 40-49: Make completion logging in the metrics-handling flow
edge-triggered rather than evaluating complete on every event. Track the
previous completion state or add a one-shot guard so the transition to
remaining_bytes == 0 logs immediately only once; subsequent completed
MetricsChanged events must follow the existing METRICS_LOG_INTERVAL throttle.

In `@crates/libtortillas/src/pieces/piece_scheduler.rs`:
- Around line 144-153: Update the cursor initialization in requests_for_peer to
handle next_piece == piece_count before calling clamp, returning empty request
ranges when all pieces are complete. Preserve normal cursor clamping for
in-progress schedules, including partial final pieces where first_slot may
exceed total_slots.

---

Nitpick comments:
In `@crates/libtortillas/src/peer/actor.rs`:
- Around line 755-761: Update PeerActor::handle so incoming PeerMessages::Piece
messages periodically publish live transfer samples even when no state-changing
publication occurs. Refresh last_rate_sample through the existing rate-sampling
path before publishing, ensuring the live PeerView contains current
metrics.transfer.samples, metrics.transfer.rates, download rate, and progress.
Preserve existing publish behavior and gate the added work consistently with the
live feature and publication settings.
🪄 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: b097dc26-1bbf-4f0c-bcf5-09ac80c34c75

📥 Commits

Reviewing files that changed from the base of the PR and between 8ee5a79 and 16ef5a5.

📒 Files selected for processing (8)
  • crates/libtortillas/examples/live.rs
  • crates/libtortillas/examples/peer_transfer.rs
  • crates/libtortillas/src/peer/actor.rs
  • crates/libtortillas/src/pieces/piece_scheduler.rs
  • crates/libtortillas/src/protocol/stream.rs
  • crates/libtortillas/src/torrent/actor.rs
  • crates/libtortillas/src/tracker/http.rs
  • crates/libtortillas/src/tracker/model.rs
💤 Files with no reviewable changes (1)
  • crates/libtortillas/src/tracker/model.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/libtortillas/src/tracker/http.rs
  • crates/libtortillas/examples/peer_transfer.rs
  • crates/libtortillas/src/torrent/actor.rs
  • crates/libtortillas/src/protocol/stream.rs

Comment on lines +40 to +49
let complete = metrics
.progress
.remaining_bytes
.is_some_and(|bytes| bytes.0 == 0);
let now = Instant::now();
if complete
|| last_metrics_log
.is_none_or(|last| now.duration_since(last) >= METRICS_LOG_INTERVAL)
{
last_metrics_log = Some(now);

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.

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Make completion logging edge-triggered.

complete remains true after remaining_bytes reaches zero, so every later MetricsChanged event bypasses the interval. If completed torrents continue emitting metrics while seeding, logging becomes unthrottled. Track the false-to-true completion transition or make completion logging a one-shot.

🤖 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/examples/live.rs` around lines 40 - 49, Make completion
logging in the metrics-handling flow edge-triggered rather than evaluating
complete on every event. Track the previous completion state or add a one-shot
guard so the transition to remaining_bytes == 0 logs immediately only once;
subsequent completed MetricsChanged events must follow the existing
METRICS_LOG_INTERVAL throttle.

Comment thread crates/libtortillas/src/pieces/piece_scheduler.rs Outdated
@artrixdotdev
artrixdotdev merged commit 99fa6a5 into main Jul 27, 2026
3 checks passed
@artrixdotdev
artrixdotdev deleted the perf/reduce-memory-usage branch July 27, 2026 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request refactor Neither fixes a bug nor adds a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant