Skip to content
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

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

msft-paddy14
Copy link
Contributor

@msft-paddy14 msft-paddy14 commented Nov 27, 2024

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

Method Mean Error StdDev Allocated
TestNetworkTask 23.08 ms 0.337 ms 0.299 ms 128.22 KB

With Changes

Job=.NET 8 EnvironmentVariables=DOTNET_TieredPGO=0 Runtime=.NET 8.0
Server=True

Method Mean Error StdDev Allocated
TestNetworkTask 18.71 ms 0.216 ms 0.202 ms 126.29 KB

Remaining BDN Results
BenchmarkMain.log
BenchmarkWithAsyncChanges.log

@msft-paddy14 msft-paddy14 marked this pull request as ready for review December 1, 2024 09:31
@msft-paddy14 msft-paddy14 requested review from vazois and yrajas December 1, 2024 09:38
@TalZaccai TalZaccai requested a review from badrishc December 3, 2024 19:22
@badrishc badrishc requested review from ReubenBond and removed request for yrajas December 5, 2024 02:51
2. Refactor continuewith to async/await pattern
benchmark/BDN.benchmark/Network/NetworkBase.cs Outdated Show resolved Hide resolved
libs/common/Networking/TcpNetworkHandlerBase.cs Outdated Show resolved Hide resolved
}
}

void NetworkBufferProcessed(object sender, SocketAsyncEventArgs e)
Copy link
Contributor

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?

Copy link
Contributor

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;
Copy link
Contributor

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)
Copy link
Contributor

@badrishc badrishc Dec 18, 2024

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);
}
Copy link
Contributor

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));

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.

3 participants