Conversation
📝 WalkthroughWalkthroughIntroduces a byte-bounded channel that enforces backpressure by total buffered bytes via a Changes
Sequence Diagram(s)sequenceDiagram
%% Participants
participant Producer as Producer
participant Sender as ByteBoundedSender
participant Sem as Semaphore
participant MPSC as "mpsc::Sender/Receiver"
participant Receiver as ByteBoundedReceiver
participant Consumer as Consumer
Producer->>Sender: send(item)
Sender->>Sender: compute permits_needed = min(item.byte_size, max_bytes)
Sender->>Sem: acquire(permits_needed)
Sem-->>Sender: permits acquired (or block)
Sender->>MPSC: send(item)
MPSC-->>Sender: OK
Sender-->>Producer: OK
Consumer->>Receiver: recv()
Receiver->>MPSC: recv()
MPSC-->>Receiver: item
Receiver->>Receiver: compute permits_to_release = min(item.byte_size, max_bytes)
Receiver->>Sem: release(permits_to_release)
Sem-->>Receiver: permits returned
Receiver-->>Consumer: item
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@src/fls/byte_channel.rs`:
- Around line 35-48: The cast in send() (permits_needed as u32) can overflow
when max_bytes/byte_size() exceed u32::MAX; add a guard in the channel
constructor (byte_bounded_channel) to ensure the provided max_bytes is <=
u32::MAX and fail early (return an Err or panic with a clear message) so send()
can safely cast to u32; also update send() to use a checked conversion (e.g.,
try_into/try_from) or rely on the validated invariant to make the cast explicit.
Ensure you reference/validate the same max_bytes used by byte_bounded_channel
and mention the failure path so callers cannot create a channel larger than
u32::MAX.
In `@tests/byte_bounded_memory.rs`:
- Around line 34-37: The test currently detects backpressure by comparing
send_duration to a hardcoded wall-clock threshold (the send_duration variable
and its comparisons against Duration::from_millis(...)) which is flaky in CI;
change both places that compare send_duration to a duration to a structural
check instead — e.g., use a non-blocking try_send (or inspect a
semaphore/channel available_permits / is_full) before performing the send and
increment backpressure_counter only when try_send fails or when you must acquire
a permit (i.e., the send would block), or if you cannot change to try_send then
relax the thresholds substantially; update the checks around
backpressure_counter and remove reliance on elapsed time so tests are robust.
- Line 2: The file currently declares an unused module import "mod common" which
causes a compiler warning; either remove the unused declaration or actually use
the utilities from that module (e.g., call create_test_data, compress_gz, or
compress_xz) in tests such as those in byte_bounded_memory.rs; locate the "mod
common" line and delete it if you don't need common helpers, or import and
invoke the specific functions (create_test_data, compress_gz, compress_xz) where
appropriate to justify keeping the module.
🧹 Nitpick comments (3)
src/fls/byte_channel.rs (1)
61-77: Permit accounting for zero-byte items.If a
SizedItemhasbyte_size() == 0, it acquires 0 permits and passes through without consuming any byte budget. This is correct but means zero-byte items are bounded only bymax_items, not bymax_bytes. If this is intentional, consider documenting it; if not, consider acquiring at least 1 permit for non-empty items.For
bytes::Bytes,len() == 0is a valid state (e.g.,Bytes::new()), so this is a realistic scenario in edge cases.src/fls/mod.rs (1)
4-4: Considerpub(crate)if the module is not part of the public API.
byte_channelis exposed aspub modalongsideautomotiveandoci. If it's only needed by integration tests, you could use#[cfg(test)] pub mod byte_channelor keep itpub(crate)and re-export only what tests need. However, if integration tests undertests/require access,pubis the simplest path.src/fls/oci/from_oci.rs (1)
2290-2296: Buffer capacity calculation duplicated across call sites.The formula
((buffer_size_mb * 1024) / 16).max(1000)appears here and is effectively the same as thebuffer_capacitycalculation inflash_from_oci(lines 1699-1701). Consider extracting this into a shared helper to keep the heuristic in one place.Sketch
fn default_buffer_item_capacity(buffer_size_mb: usize) -> usize { ((buffer_size_mb * 1024) / 16).max(1000) }
Currently the download buffer is bounded by item count, this is ok if chunks are 16KB, However if we get 256KB chunks for example, we go over the 128MB limit. This patch uses ByteBoundChannel to enforce the byte limit, even we are under the chunk size limit Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com> Assisted-by: claude-opus-4.5
e41c71d to
764efde
Compare
Currently the download buffer is bounded by item count, this is ok if chunks are 16KB,
However if we get 256KB chunks for example, we go over the 128MB limit.
This patch uses ByteBoundChannel to enforce the byte limit, even we are under the chunk
size limit
Summary by CodeRabbit
Release Notes
New Features
Tests