-
-
Notifications
You must be signed in to change notification settings - Fork 363
feat(DelimiterDataPackageHandler): add DelimiterDataPackageHandler class #6260
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 GuideIntroduces a new DelimiterDataPackageHandler class for splitting and processing byte-delimited data packages, augments unit tests with a corresponding test and helper, and updates existing test port numbers to avoid conflicts. Class diagram for DelimiterDataPackageHandler and its relationship to DataPackageHandlerBaseclassDiagram
class DataPackageHandlerBase {
<<abstract>>
+Task ReceiveAsync(Memory<byte> data)
+Func<byte[], Task>? ReceivedCallBack
+Memory<byte> ConcatBuffer(Memory<byte> data)
+void SlicePackage(Memory<byte> data, int length)
}
class DelimiterDataPackageHandler {
-ReadOnlyMemory<byte> _delimiter
+DelimiterDataPackageHandler(string delimiter, Encoding? encoding = null)
+DelimiterDataPackageHandler(byte[] delimiter)
+override Task ReceiveAsync(Memory<byte> data)
}
DataPackageHandlerBase <|-- DelimiterDataPackageHandler
Class diagram for DelimiterDataPackageHandler constructors and key membersclassDiagram
class DelimiterDataPackageHandler {
-ReadOnlyMemory<byte> _delimiter
+DelimiterDataPackageHandler(string delimiter, Encoding? encoding = null)
+DelimiterDataPackageHandler(byte[] delimiter)
+override Task ReceiveAsync(Memory<byte> data)
}
File-Level Changes
Assessment against 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 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/DelimiterDataPackageHandler.cs:58` </location>
<code_context>
+ {
+ data = ConcatBuffer(data);
+
+ var index = data.Span.IndexOfAny(_delimiter.Span);
+ var segment = index == -1 ? data : data[..index];
+
</code_context>
<issue_to_address>
Using IndexOfAny with a multi-byte delimiter may not match the intended delimiter sequence.
IndexOfAny matches any single byte from the delimiter, which can cause incorrect splits if the delimiter is multi-byte. Use a method that searches for the full delimiter sequence to ensure correct segmentation.
</issue_to_address>
### Comment 2
<location> `test/UnitTest/Services/TcpSocketFactoryTest.cs:177` </location>
<code_context>
[Fact]
public async Task FixLengthDataPackageHandler_Ok()
{
</code_context>
<issue_to_address>
Missing edge case tests for DelimiterDataPackageHandler.
Please add tests for these edge cases: missing delimiter (data should be buffered), multiple packages in one read (callback for each), delimiter split across reads (correct reassembly), empty payloads (delimiter first), and consecutive delimiters (empty package between). This will improve robustness.
</issue_to_address>
### Comment 3
<location> `test/UnitTest/Services/TcpSocketFactoryTest.cs:298` </location>
<code_context>
+ await tcs.Task;
+
+ // 验证接收到的数据
+ Assert.Equal(receivedBuffer.ToArray(), [1, 2, 3, 4, 5, 0x13, 0x10]);
+
+ // 关闭连接
</code_context>
<issue_to_address>
Assertion order: expected and actual values should be swapped.
Swap the arguments so the expected value is first and the actual value is second: Assert.Equal([1, 2, 3, 4, 5, 0x13, 0x10], receivedBuffer.ToArray());. This improves test output clarity.
</issue_to_address>
### Comment 4
<location> `test/UnitTest/Services/TcpSocketFactoryTest.cs:280` </location>
<code_context>
+ Memory<byte> receivedBuffer = Memory<byte>.Empty;
+
+ // 增加数据库处理适配器
+ client.SetDataHandler(new DelimiterDataPackageHandler(new byte[] { 0x13, 0x10 })
+ {
+ ReceivedCallBack = buffer =>
</code_context>
<issue_to_address>
No test for string-based delimiter constructor.
Please add tests for the string-based constructor, both with and without the encoding parameter, to ensure full coverage.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
// 增加数据库处理适配器
client.SetDataHandler(new DelimiterDataPackageHandler(new byte[] { 0x13, 0x10 })
{
ReceivedCallBack = buffer =>
{
receivedBuffer = buffer;
tcs.SetResult();
return Task.CompletedTask;
}
});
=======
// 增加数据库处理适配器
client.SetDataHandler(new DelimiterDataPackageHandler(new byte[] { 0x13, 0x10 })
{
ReceivedCallBack = buffer =>
{
receivedBuffer = buffer;
tcs.SetResult();
return Task.CompletedTask;
}
});
// Test: string-based delimiter constructor (default encoding)
var tcsStringDelimiter = new TaskCompletionSource();
Memory<byte> receivedBufferStringDelimiter = Memory<byte>.Empty;
var stringDelimiterHandler = new DelimiterDataPackageHandler("\r\n")
{
ReceivedCallBack = buffer =>
{
receivedBufferStringDelimiter = buffer;
tcsStringDelimiter.SetResult();
return Task.CompletedTask;
}
};
client.SetDataHandler(stringDelimiterHandler);
await client.SendAsync(data);
await tcsStringDelimiter.Task;
Assert.Equal(data.ToArray(), receivedBufferStringDelimiter.ToArray());
// Test: string-based delimiter constructor (with encoding)
var tcsStringDelimiterEncoding = new TaskCompletionSource();
Memory<byte> receivedBufferStringDelimiterEncoding = Memory<byte>.Empty;
var stringDelimiterHandlerEncoding = new DelimiterDataPackageHandler("\r\n", System.Text.Encoding.UTF8)
{
ReceivedCallBack = buffer =>
{
receivedBufferStringDelimiterEncoding = buffer;
tcsStringDelimiterEncoding.SetResult();
return Task.CompletedTask;
}
};
client.SetDataHandler(stringDelimiterHandlerEncoding);
await client.SendAsync(data);
await tcsStringDelimiterEncoding.Task;
Assert.Equal(data.ToArray(), receivedBufferStringDelimiterEncoding.ToArray());
>>>>>>> REPLACE
</suggested_fix>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| { | ||
| data = ConcatBuffer(data); | ||
|
|
||
| var index = data.Span.IndexOfAny(_delimiter.Span); |
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.
issue (bug_risk): Using IndexOfAny with a multi-byte delimiter may not match the intended delimiter sequence.
IndexOfAny matches any single byte from the delimiter, which can cause incorrect splits if the delimiter is multi-byte. Use a method that searches for the full delimiter sequence to ensure correct segmentation.
|
|
||
| // 关闭连接 | ||
| client.Close(); | ||
| StopTcpServer(server); |
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.
suggestion (testing): Missing edge case tests for DelimiterDataPackageHandler.
Please add tests for these edge cases: missing delimiter (data should be buffered), multiple packages in one read (callback for each), delimiter split across reads (correct reassembly), empty payloads (delimiter first), and consecutive delimiters (empty package between). This will improve robustness.
| await tcs.Task; | ||
|
|
||
| // 验证接收到的数据 | ||
| Assert.Equal(receivedBuffer.ToArray(), [1, 2, 3, 4, 5, 0x13, 0x10]); |
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.
nitpick (testing): Assertion order: expected and actual values should be swapped.
Swap the arguments so the expected value is first and the actual value is second: Assert.Equal([1, 2, 3, 4, 5, 0x13, 0x10], receivedBuffer.ToArray());. This improves test output clarity.
| // 增加数据库处理适配器 | ||
| client.SetDataHandler(new DelimiterDataPackageHandler(new byte[] { 0x13, 0x10 }) | ||
| { | ||
| ReceivedCallBack = buffer => | ||
| { | ||
| receivedBuffer = buffer; | ||
| tcs.SetResult(); | ||
| return Task.CompletedTask; | ||
| } | ||
| }); |
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.
suggestion (testing): No test for string-based delimiter constructor.
Please add tests for the string-based constructor, both with and without the encoding parameter, to ensure full coverage.
| // 增加数据库处理适配器 | |
| client.SetDataHandler(new DelimiterDataPackageHandler(new byte[] { 0x13, 0x10 }) | |
| { | |
| ReceivedCallBack = buffer => | |
| { | |
| receivedBuffer = buffer; | |
| tcs.SetResult(); | |
| return Task.CompletedTask; | |
| } | |
| }); | |
| // 增加数据库处理适配器 | |
| client.SetDataHandler(new DelimiterDataPackageHandler(new byte[] { 0x13, 0x10 }) | |
| { | |
| ReceivedCallBack = buffer => | |
| { | |
| receivedBuffer = buffer; | |
| tcs.SetResult(); | |
| return Task.CompletedTask; | |
| } | |
| }); | |
| // Test: string-based delimiter constructor (default encoding) | |
| var tcsStringDelimiter = new TaskCompletionSource(); | |
| Memory<byte> receivedBufferStringDelimiter = Memory<byte>.Empty; | |
| var stringDelimiterHandler = new DelimiterDataPackageHandler("\r\n") | |
| { | |
| ReceivedCallBack = buffer => | |
| { | |
| receivedBufferStringDelimiter = buffer; | |
| tcsStringDelimiter.SetResult(); | |
| return Task.CompletedTask; | |
| } | |
| }; | |
| client.SetDataHandler(stringDelimiterHandler); | |
| await client.SendAsync(data); | |
| await tcsStringDelimiter.Task; | |
| Assert.Equal(data.ToArray(), receivedBufferStringDelimiter.ToArray()); | |
| // Test: string-based delimiter constructor (with encoding) | |
| var tcsStringDelimiterEncoding = new TaskCompletionSource(); | |
| Memory<byte> receivedBufferStringDelimiterEncoding = Memory<byte>.Empty; | |
| var stringDelimiterHandlerEncoding = new DelimiterDataPackageHandler("\r\n", System.Text.Encoding.UTF8) | |
| { | |
| ReceivedCallBack = buffer => | |
| { | |
| receivedBufferStringDelimiterEncoding = buffer; | |
| tcsStringDelimiterEncoding.SetResult(); | |
| return Task.CompletedTask; | |
| } | |
| }; | |
| client.SetDataHandler(stringDelimiterHandlerEncoding); | |
| await client.SendAsync(data); | |
| await tcsStringDelimiterEncoding.Task; | |
| Assert.Equal(data.ToArray(), receivedBufferStringDelimiterEncoding.ToArray()); |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #6260 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 710 711 +1
Lines 31339 31375 +36
Branches 4424 4431 +7
=========================================
+ Hits 31339 31375 +36
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:
|
Link issues
fixes #6259
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Implement delimiter-based data package handling in the TCP socket service and add corresponding unit tests.
New Features:
Enhancements: