-
-
Notifications
You must be signed in to change notification settings - Fork 363
feat(FixLengthDataPackageHandler): support multiple sticky package #6262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Reviewer's GuideRefactor the fixed-length data package handler to loop through and dispatch multiple complete packages per receive call, replacing the previous buffer concatenation and slicing logic, and adjust unit tests to simulate and assert reception of multiple sequential packages with updated payloads and timings. Sequence diagram for handling multiple sticky packages in FixLengthDataPackageHandler.ReceiveAsyncsequenceDiagram
participant Client
participant FixLengthDataPackageHandler
participant ReceivedCallBack
Client->>FixLengthDataPackageHandler: ReceiveAsync(data)
loop While data contains at least one full package
FixLengthDataPackageHandler->>FixLengthDataPackageHandler: Copy segment to buffer
FixLengthDataPackageHandler->>FixLengthDataPackageHandler: Update _receivedLength
alt _receivedLength == length
FixLengthDataPackageHandler->>ReceivedCallBack: await ReceivedCallBack(_data)
FixLengthDataPackageHandler->>FixLengthDataPackageHandler: Reset _receivedLength
end
FixLengthDataPackageHandler->>FixLengthDataPackageHandler: Slice data for next package
end
Class diagram for updated FixLengthDataPackageHandlerclassDiagram
class DataPackageHandlerBase {
<<abstract>>
+Task ReceiveAsync(Memory<byte> data)
}
class FixLengthDataPackageHandler {
- int length
- int _receivedLength
- byte[] _data
+ Func<byte[], Task>? ReceivedCallBack
+ override Task ReceiveAsync(Memory<byte> data)
}
DataPackageHandlerBase <|-- FixLengthDataPackageHandler
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ArgoZhang - I've reviewed your changes - here's some feedback:
- Refactor the ReceiveAsync loop to use a
while (data.Length >= length)pattern for full‐package extraction and then handle any remainder outside the loop to reduce nested conditions. - Extract the buffer slicing and concatenation steps into a dedicated helper (e.g.
TryExtractPackage) so ReceiveAsync stays concise and avoids duplicated length checks. - In the unit test, remove the redundant consecutive
await tcs.Taskcalls and adjust the TaskCompletionSource logic to clearly match each expected callback invocation.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Refactor the ReceiveAsync loop to use a `while (data.Length >= length)` pattern for full‐package extraction and then handle any remainder outside the loop to reduce nested conditions.
- Extract the buffer slicing and concatenation steps into a dedicated helper (e.g. `TryExtractPackage`) so ReceiveAsync stays concise and avoids duplicated length checks.
- In the unit test, remove the redundant consecutive `await tcs.Task` calls and adjust the TaskCompletionSource logic to clearly match each expected callback invocation.
## Individual Comments
### Comment 1
<location> `src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs:31` </location>
<code_context>
- segment.CopyTo(_data[_receivedLength..]);
-
- if (data.Length > len)
+ while (data.Length > 0)
{
- SlicePackage(data, data.Length - len);
</code_context>
<issue_to_address>
Consider refactoring the loop to compute copy lengths once, use a single data slice per iteration, and clearly separate full and partial packet handling.
Here’s a shorter version that keeps the exact behavior but collapses the nested‐ifs into a single loop, does the `Slice` only once per iteration, and makes the “full‐packet vs leftover” logic explicit:
```csharp
public override async Task ReceiveAsync(Memory<byte> data)
{
data = ConcatBuffer(data);
while (data.Length > 0)
{
// copy up to the remaining bytes needed for one packet
int needed = length - _receivedLength;
int toCopy = Math.Min(needed, data.Length);
data.Slice(0, toCopy).CopyTo(_data[_receivedLength..]);
_receivedLength += toCopy;
// advance the input buffer
data = data.Slice(toCopy);
if (_receivedLength == length)
{
// complete packet → callback & reset
_receivedLength = 0;
if (ReceivedCallBack != null)
await ReceivedCallBack(_data);
// continue to consume any further packets in 'data'
continue;
}
// incomplete packet with leftover input → cache and exit
if (data.Length > 0)
{
SlicePackage(data, data.Length);
}
break;
}
}
```
**What changed**
- Compute `toCopy = Min(needed, data.Length)` once.
- Always `data = data.Slice(toCopy)` rather than conditional slices in two places.
- Split the “packet complete” vs “partial packet” paths into two clear branches.
- No repeated `segment.Length + length` checks—just one `continue` for full packets, one `break` for leftovers.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs
Show resolved
Hide resolved
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #6262 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 711 711
Lines 31375 31374 -1
Branches 4431 4431
=========================================
- Hits 31375 31374 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@sourcery-ai review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ArgoZhang - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs:33` </location>
<code_context>
-
- // 拷贝数据
- var len = length - _receivedLength;
- var segment = data.Length > len ? data[..len] : data;
- segment.CopyTo(_data[_receivedLength..]);
-
</code_context>
<issue_to_address>
Consider validating that 'len' is always positive.
If '_receivedLength' exceeds 'length', 'len' becomes negative, which can cause a slicing exception. Add a check to ensure 'len' is positive before using it.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ArgoZhang - I've reviewed your changes and they look great!
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Link issues
fixes #6261
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Enable FixLengthDataPackageHandler to iteratively process all complete fixed-length packages from incoming streams and extend its unit test to validate multiple consecutive callbacks
New Features:
Bug Fixes:
Tests: