-
Notifications
You must be signed in to change notification settings - Fork 538
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
Convert sync over async network handling to async #835
base: main
Are you sure you want to change the base?
Conversation
This reverts commit 1b3dca6.
2. Refactor continuewith to async/await pattern
…om:microsoft/garnet into users/padgupta/add_async_socket_processing
} | ||
} | ||
|
||
void NetworkBufferProcessed(object sender, SocketAsyncEventArgs e) |
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.
Is this method necessary? Can we move the enclosed piece of code in the caller instead?
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.
yes, please revert this method and inline it as it was earlier
@@ -144,22 +151,37 @@ void RecvEventArg_Completed(object sender, SocketAsyncEventArgs e) | |||
{ | |||
// No more things to receive | |||
Dispose(e); | |||
break; | |||
return; |
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.
Revert this back to break
?
e.SetBuffer(networkReceiveBuffer, networkBytesRead, networkReceiveBuffer.Length - networkBytesRead); | ||
} while (!e.AcceptSocket.ReceiveAsync(e)); | ||
var receiveTask = OnNetworkReceiveAsync(e.BytesTransferred); | ||
if (!receiveTask.IsCompleted) |
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.
!IsCompletedSuccessfully
is better than !IsCompleted
because it excludes faulted and canceled tasks, allowing the await to properly capture and rethrow those exceptions.
await receiveTask; | ||
} | ||
NetworkBufferProcessed(sender, e); | ||
} |
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.
nit: while
should be on same line as }
to maintain parity with style on main
:
do
{
} while (!e.AcceptSocket.ReceiveAsync(e));
Currently Garnet's network processing in TLS mode happens by blocking the thread that receives the packet and it waits for TLS processing to complete. This leads to threadpool exhaustion and is an anti-pattern in general. It limits scalability where cores are limited as threads will get blocked and .NET will create more threads (where limit is not set). This makes things worst as memory footprint increases (~8MB per stack) and thread contention increases. We also convert Task to ValueTask for paths where async operation is already completed in general
BDN results for Network test added
BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2605) (Hyper-V)
AMD EPYC 7763, 1 CPU, 16 logical and 8 physical cores
.NET SDK 9.0.100
[Host] : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
.NET 8 : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
Job=.NET 8 EnvironmentVariables=DOTNET_TieredPGO=0 Runtime=.NET 8.0
Server=True
Without changes
With Changes
Job=.NET 8 EnvironmentVariables=DOTNET_TieredPGO=0 Runtime=.NET 8.0
Server=True
Remaining BDN Results
BenchmarkMain.log
BenchmarkWithAsyncChanges.log