Skip to content

Refactor fragmentation: move fragment_packet to fragment crate#436

Merged
leynos merged 2 commits intomainfrom
refactor-fragment-packet-module-0qwqyz
Feb 3, 2026
Merged

Refactor fragmentation: move fragment_packet to fragment crate#436
leynos merged 2 commits intomainfrom
refactor-fragment-packet-module-0qwqyz

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Feb 2, 2026

Summary

  • Refactors fragmentation: centralizes fragment_packet in the fragment crate and adds Fragmentable/FragmentParts
  • Keeps backward compatibility via re-exports and canonical path changes
  • Improves layering by consolidating fragmentation logic in the fragment module
  • Adds envelope blanket Fragmentable implementation for all Packet types

Changes

Core changes

  • Added new module: src/fragment/packet.rs implementing fragment_packet along with FragmentParts and Fragmentable
  • Created pub mod packet in src/fragment/mod.rs and exposed fragment_packet, FragmentParts, and Fragmentable publicly
  • Exported FragmentParts and Fragmentable from crate::fragment for convenient access
  • Updated src/app/envelope.rs to provide a blanket implementation: any Packet now implements Fragmentable
  • Updated src/app/fragmentation_state.rs to accept E: Fragmentable and call crate::fragment::fragment_packet instead of app-layer path
  • Updated src/app/fragment_utils.rs to re-export the canonical fragment_packet from crate::fragment, preserving existing imports

Compatibility

  • Re-export ensures existing code paths continue to compile without changes

Behavior

  • Fragmentation behavior remains unchanged: oversized payloads are split into frames with preserved IDs and correlation IDs

Why

  • Improves layering by moving fragmentation logic into the fragment crate, avoiding cross-layer dependencies

Test plan

  • cargo test
  • Build and run tests to ensure no regressions
  • Optionally test with an oversized payload to verify fragmentation frames are produced as before

◳ Generated by DevBoxer


ℹ️ Tag @devboxerhub to ask questions and address PR feedback

📎 Task: https://www.devboxer.com/task/58637d28-099d-4210-84c7-3b4d55874cd5

📝 Closes #431

Summary by Sourcery

Centralize packet fragmentation logic in the fragment module while preserving existing public APIs.

Enhancements:

  • Move the packet fragmentation helper into a new fragment::packet module and expose it via the fragment crate API.
  • Update app-layer fragmentation state to depend on the fragment-layer fragment_packet function instead of an app-local helper.
  • Re-export fragment_packet from the existing app::fragment_utils module to maintain backward-compatible imports.

Resolves the layering violation where `fragment_packet` was defined in
`app::fragment_utils` but used by the connection actor. The function now
resides in its canonical location at `fragment::packet` alongside other
fragmentation primitives, while preserving backward compatibility
through a re-export from the original `app::fragment_utils` path.

This follows the modularisation pattern established in PR #424.

Closes #431

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Feb 2, 2026

Reviewer's Guide

Centralizes packet fragmentation logic in the fragment module by introducing a new fragment::packet module, moving the fragment_packet implementation there, updating internal callers to use it, and re-exporting the function from both the fragment crate and the existing app-level helper for backward compatibility.

Class diagram for centralized fragment_packet in fragment packet module

classDiagram
    class fragment_mod {
        <<module>>
    }
    class fragment_packet_mod {
        <<module>>
        +fragment_packet(fragmenter, packet) Result_vec_E_FragmentationError
    }
    class app_fragment_utils_mod {
        <<module>>
        +fragment_packet(fragmenter, packet) Result_vec_E_FragmentationError
    }
    class app_fragmentation_state {
        <<struct>>
        -fragmenter Fragmenter
        +fragment(packet) Result_vec_E_FragmentationError
    }

    class Fragmenter {
        +fragment_bytes(payload) FragmentBatch
    }

    class FragmentBatch {
        +is_fragmented() bool
        +len() usize
        +into_iter() Iterator_FragmentFrame
    }

    class FragmentFrame {
        +into_parts() FragmentHeader_payload_bytes
    }

    class FragmentHeader {
    }

    class FragmentationError {
    }

    class Packet {
        <<trait>>
        +into_parts() PacketParts
        +from_parts(parts) Self
    }

    class PacketParts {
        +new(id, correlation_id, payload) PacketParts
        +id() MessageId
        +correlation_id() CorrelationId
        +payload() bytes
    }

    class MessageId {
    }

    class CorrelationId {
    }

    class payload_mod {
        <<module>>
        +encode_fragment_payload(header, payload) bytes_or_error
    }

    fragment_mod <|-- fragment_packet_mod
    fragment_mod <|-- payload_mod

    app_fragment_utils_mod --> fragment_packet_mod : re_exports_fragment_packet

    app_fragmentation_state --> Fragmenter
    app_fragmentation_state --> fragment_packet_mod : uses_fragment_packet

    fragment_packet_mod --> Fragmenter
    fragment_packet_mod --> Packet
    fragment_packet_mod --> PacketParts
    fragment_packet_mod --> FragmentationError
    fragment_packet_mod --> payload_mod : encode_fragment_payload
    fragment_packet_mod --> FragmentBatch
    FragmentBatch --> FragmentFrame
    FragmentFrame --> FragmentHeader
    FragmentFrame --> payload_mod
    PacketParts --> MessageId
    PacketParts --> CorrelationId
Loading

Flow diagram for fragment_packet call paths after refactor

flowchart LR
    subgraph app_layer
        app_callers[app callers using fragment_packet]
        app_fragment_utils_mod[app::fragment_utils module]
        app_fragmentation_state[app::FragmentationState.fragment]
    end

    subgraph fragment_layer
        fragment_packet_mod[fragment::packet::fragment_packet]
        fragment_mod_exports[fragment::mod re_export]
    end

    app_callers -->|existing imports| app_fragment_utils_mod
    app_fragment_utils_mod -->|re_export call| fragment_packet_mod

    app_fragmentation_state -->|direct call| fragment_packet_mod

    fragment_packet_mod --> fragment_mod_exports
Loading

File-Level Changes

Change Details Files
Move the fragment_packet implementation into the fragment layer and expose it via the fragment crate API.
  • Added new src/fragment/packet.rs module containing the fragment_packet implementation that operates on Packet and PacketParts using Fragmenter and encode_fragment_payload.
  • Updated src/fragment/mod.rs to declare the new packet module and publicly re-export fragment_packet from it alongside existing fragment types and helpers.
src/fragment/packet.rs
src/fragment/mod.rs
Update application-layer code to depend on the fragment-layer fragment_packet while maintaining backward-compatible imports.
  • Replaced the direct call to crate::app::fragment_utils::fragment_packet in FragmentationState with crate::fragment::fragment_packet to fix the layering dependency.
  • Simplified src/app/fragment_utils.rs to remove its local fragment_packet implementation and instead re-export crate::fragment::fragment_packet, preserving existing public API for callers.
src/app/fragmentation_state.rs
src/app/fragment_utils.rs

Assessment against linked issues

Issue Objective Addressed Explanation
#431 Move the fragment_packet implementation from the app layer into a dedicated non-app fragment module.
#431 Preserve the existing public API by re-exporting fragment_packet from the app module.
#431 Update all call sites (including the connection actor) to use the new fragment-level fragment_packet location, eliminating the layering violation.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 2, 2026

Summary by CodeRabbit

  • New Features

    • Adds transport-level packet fragmentation and reassembly support, with a public API for fragmentable packets and payload parts.
    • Enables automatic fragmentation for existing packet types without per-type boilerplate.
  • Refactor

    • Internal fragmentation utilities reorganised and consolidated; original local helper retained as a deprecated alias for compatibility.

Walkthrough

Move the transport-level fragmentation logic out of app into a dedicated fragment::packet module, introduce FragmentParts and Fragmentable, adapt FragmentationState to use Fragmentable, and keep a deprecated re-export in src/app/fragment_utils.rs for backward compatibility.

Changes

Cohort / File(s) Summary
New fragment packet module
src/fragment/packet.rs, src/fragment/mod.rs
Add packet submodule implementing FragmentParts, Fragmentable trait and fragment_packet; re-export FragmentParts, Fragmentable, and fragment_packet from fragment module.
App compatibility shim
src/app/fragment_utils.rs
Remove local fragment_packet implementation; add deprecated pub use crate::fragment::fragment_packet; re-export to preserve old public path.
Fragmentation consumer update
src/app/fragmentation_state.rs
Change method generic bound from E: Packet to E: Fragmentable and delegate to crate::fragment::fragment_packet.
Blanket impl for existing Packets
src/app/envelope.rs
Add impl<T: Packet> Fragmentable for T to bridge existing Packet types to new Fragmentable API automatically.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

✂️ Layers sliced, the packets roam,
New module born, a tidy home,
Re-exports whisper, old paths kept,
Fragments dance where logic leapt 🧩

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarises the main refactoring: moving fragment_packet from the app layer to the fragment crate.
Description check ✅ Passed The description provides a comprehensive explanation of changes, rationale, and testing approach, directly related to the refactoring work.
Linked Issues check ✅ Passed The pull request fully addresses #431: moves fragment_packet to src/fragment/packet.rs, re-exports from app for compatibility, and updates callers to the new location.
Out of Scope Changes check ✅ Passed All changes directly support the refactoring objective of moving fragmentation logic from app to fragment crate. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor-fragment-packet-module-0qwqyz

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

@leynos leynos marked this pull request as ready for review February 2, 2026 02:19
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The new fragment::packet module still depends on crate::app::{Packet, PacketParts}, so the layering violation is only partially addressed; consider introducing a fragmentation-facing trait or abstraction in the fragment layer so it no longer needs to depend on app types.
  • If app::fragment_utils::fragment_packet is now just a compatibility shim, consider marking the re-export as #[deprecated] with guidance to migrate to crate::fragment::fragment_packet to make the transition path explicit.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `fragment::packet` module still depends on `crate::app::{Packet, PacketParts}`, so the layering violation is only partially addressed; consider introducing a fragmentation-facing trait or abstraction in the fragment layer so it no longer needs to depend on `app` types.
- If `app::fragment_utils::fragment_packet` is now just a compatibility shim, consider marking the re-export as `#[deprecated]` with guidance to migrate to `crate::fragment::fragment_packet` to make the transition path explicit.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Addresses code review feedback on the fragment_packet refactoring:

1. Introduces `Fragmentable` trait and `FragmentParts` type in the
   fragment module, removing the dependency on `crate::app::{Packet,
   PacketParts}`. The fragmentation layer now operates on its own
   abstractions.

2. Adds a blanket implementation in the app module so all `Packet`
   types automatically implement `Fragmentable`, preserving backward
   compatibility.

3. Marks `app::fragment_utils::fragment_packet` as deprecated with
   guidance to migrate to `crate::fragment::fragment_packet`.

This completes the layering fix: the fragment module no longer depends
on app-layer types, and the transition path for callers is explicit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@leynos leynos changed the title Refactor: Move fragment_packet to fragment crate and re-export Refactor fragmentation: move fragment_packet to fragment crate Feb 2, 2026
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Feb 3, 2026

@coderabbitai Have the following now been resolved?

  • The new fragment::packet module still depends on crate::app::{Packet, PacketParts}, so the layering violation is only partially addressed; consider introducing a fragmentation-facing trait or abstraction in the fragment layer so it no longer needs to depend on app types.
  • If app::fragment_utils::fragment_packet is now just a compatibility shim, consider marking the re-export as #[deprecated] with guidance to migrate to crate::fragment::fragment_packet to make the transition path explicit.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 3, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check src/fragment/packet.rs for imports and trait definition
echo "=== src/fragment/packet.rs ==="
cat src/fragment/packet.rs

Length of output: 3424


🏁 Script executed:

#!/bin/bash
# Check src/app/fragment_utils.rs for deprecated re-export
echo "=== src/app/fragment_utils.rs ==="
cat src/app/fragment_utils.rs

Length of output: 523


🏁 Script executed:

#!/bin/bash
# Check src/app/envelope.rs for blanket impl
echo "=== src/app/envelope.rs (blanket impl section) ==="
# Look for the Fragmentable implementation
rg -A 20 "impl.*Fragmentable" src/app/envelope.rs

Length of output: 541


@leynos: Yes, both concerns have been fully resolved!

1. Layering violation eliminated:

The fragment module now defines FragmentParts to "avoid a layering violation where fragmentation depends on app types", and the Fragmentable trait "intentionally avoids depending on application-layer types".

Evidence:

  • src/fragment/packet.rs imports only super::{FragmentationError, Fragmenter, encode_fragment_payload} with no dependencies on crate::app
  • FragmentParts replaces the previous dependency on PacketParts
  • Fragmentable trait provides the abstraction needed for fragmentation
  • The blanket implementation impl<T: Packet> Fragmentable for T in src/app/envelope.rs maintains compatibility by bridging app-layer types to the fragment layer

2. Deprecation marking added:

The re-export in src/app/fragment_utils.rs is now properly marked:

#[deprecated(
    since = "0.3.0",
    note = "use `crate::fragment::fragment_packet` instead"
)]
pub use crate::fragment::fragment_packet;

The module documentation also clearly states the deprecation and migration path. This provides an explicit transition path whilst maintaining backward compatibility.

🐰✨

@leynos leynos merged commit 7fbf62a into main Feb 3, 2026
6 checks passed
@leynos leynos deleted the refactor-fragment-packet-module-0qwqyz branch February 3, 2026 18:42
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.

Untangle layering: move fragment_packet from app to dedicated module

1 participant