Skip to content

feat(15): Zero-copy PDU infrastructure - #34

Merged
jas88 merged 4 commits into
mainfrom
pr/phase-15-zero-copy
Feb 3, 2026
Merged

jas88 merged 4 commits into
mainfrom
pr/phase-15-zero-copy

Conversation

@jas88

@jas88 jas88 commented Feb 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add SlabMemoryPool for efficient 4KB slab allocation (avoids LOH pressure)
  • Add SocketPipe wrapper with PipeReader/PipeWriter for zero-copy network I/O
  • Includes 20 comprehensive tests

Test plan

  • All Pipes tests pass (20 tests)
  • Build succeeds across all target frameworks

High-level PR Summary

This PR introduces zero-copy network I/O infrastructure for efficient PDU handling in DICOM network operations. It adds a custom SlabMemoryPool for managing fixed 4KB memory slabs that avoid Large Object Heap (LOH) pressure during high-throughput scenarios, and a SocketPipe wrapper that integrates sockets with the PipeReader/PipeWriter pattern for zero-copy buffering with backpressure support. The implementation includes background read/write pumps for async socket operations, automatic memory pooling and reuse, and comprehensive test coverage with 20 tests validating concurrent access, bidirectional communication, large data handling, and proper resource cleanup.

⏱️ Estimated Review Time: 30-90 minutes

💡 Review Order Suggestion
Order File Path
1 src/SharpDicom/Network/Pipes/SlabMemoryPool.cs
2 tests/SharpDicom.Tests/Network/Pipes/SlabMemoryPoolTests.cs
3 src/SharpDicom/Network/Pipes/SocketPipe.cs
4 tests/SharpDicom.Tests/Network/Pipes/SocketPipeTests.cs

Need help? Join our Discord


Summary by cubic

Adds SlabMemoryPool and SocketPipe to enable zero-copy PDU network I/O with backpressure and pooled 4KB buffers. Meets Phase 15 requirements by reducing allocations and GC/LOH pressure while wiring sockets to PipeReader/PipeWriter.

  • New Features

    • SlabMemoryPool: 4KB slab allocator with a capped pool (up to 1024 slabs), ArrayPool fallback for large requests, and thread-safe rent/return.
    • SocketPipe: Adapter exposing PipeReader/PipeWriter over a Socket with background pumps, configurable pause/resume thresholds, custom MemoryPool support, and clean cancellation/completion.
  • Bug Fixes

    • Handle partial sends by looping until each segment is fully transmitted.
    • Shutdown and close the socket in DisposeAsync to unblock pending I/O and ensure pumps complete.

Written for commit 1e3a839. Summary will update on new commits.

…cketPipe

Add high-performance network I/O primitives for DICOM PDU handling:
- SlabMemoryPool: 4KB slab allocator avoiding LOH pressure
- SocketPipe: PipeReader/PipeWriter wrapper with backpressure support

Part of Phase 15 - Zero-copy PDU handling.

@recurseml recurseml Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review by RecurseML

🔍 Review performed on c986ec5..d30c5d1

✨ No bugs found, your code is sparkling clean

✅ Files analyzed, no issues (4)

• src/SharpDicom/Network/Pipes/SlabMemoryPool.cs
• src/SharpDicom/Network/Pipes/SocketPipe.cs
• tests/SharpDicom.Tests/Network/Pipes/SlabMemoryPoolTests.cs
• tests/SharpDicom.Tests/Network/Pipes/SocketPipeTests.cs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 4 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/SharpDicom/Network/Pipes/SocketPipe.cs">

<violation number="1" location="src/SharpDicom/Network/Pipes/SocketPipe.cs:196">
P1: Handle partial sends: Socket.SendAsync may send fewer bytes than requested, so a single call can drop data when you advance the pipe to buffer.End. Loop until the entire segment is sent.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/SharpDicom/Network/Pipes/SocketPipe.cs Outdated
jas88 added 3 commits February 2, 2026 11:55
- Add 60s per-test timeout and 10min session timeout via runsettings
- Add 15 minute job timeout to CI workflow
- Reference runsettings in dotnet test commands
Socket.SendAsync may send fewer bytes than requested. Loop until
the entire segment is sent to prevent data loss.
netstandard2.0 Socket.ReceiveAsync/SendAsync don't accept
CancellationToken, so cancellation alone can't unblock them.
Shutdown and close the socket to ensure background tasks complete.
@codecov

codecov Bot commented Feb 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.88060% with 35 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.65%. Comparing base (c986ec5) to head (1e3a839).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/SharpDicom/Network/Pipes/SocketPipe.cs 68.42% 26 Missing and 4 partials ⚠️
src/SharpDicom/Network/Pipes/SlabMemoryPool.cs 87.17% 3 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #34      +/-   ##
==========================================
- Coverage   74.66%   74.65%   -0.01%     
==========================================
  Files         182      184       +2     
  Lines       13980    14114     +134     
  Branches     2611     2631      +20     
==========================================
+ Hits        10438    10537      +99     
- Misses       2777     2806      +29     
- Partials      765      771       +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jas88
jas88 merged commit ac70306 into main Feb 3, 2026
5 of 7 checks passed
@jas88
jas88 deleted the pr/phase-15-zero-copy branch February 3, 2026 00:10
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