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

Add new optional SocketPipe transport #1480

Closed
wants to merge 13 commits into from

Conversation

adamsitnik
Copy link
Contributor

This PR adds a simplified transport that is still using the abstraction of pipes, but it has it's own simplified logic that does not take any locks and does not use any extra tasks

For JSON Platform we jump from 920k to 1065k, in a separate PR I am going to send some improvements that take it to 1100k

@davidfowl could you please take a look?

options.IOQueueCount = threadCount;
}
#if NETCOREAPP5_0
typeof(SocketTransportOptions).GetProperty("WaitForDataBeforeAllocatingBuffer")?.SetValue(options, false);
Copy link
Member

Choose a reason for hiding this comment

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

@sebastienros @halter73 What's the deal with this? Don't we have the bits yet?

Copy link
Member

Choose a reason for hiding this comment

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

The aspnet repos might not be up to date with the latest sdk. Alternatively we can force it in the driver command line.

Copy link
Member

Choose a reason for hiding this comment

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

This was merged a while ago. It should work with a recent enough $(MicrosoftAspNetCoreAppPackageVersion). We probably need to look at updating the csproj or dependencies.props.

Copy link
Member

Choose a reason for hiding this comment

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

I set --sdk 5.0.100-preview.4.20202.8 in the baseline KPI runs.

Let me try to update the sdk in the aspnet repos, I did it last time.

{
// more or less a copy of https://github.com/dotnet/aspnetcore/blob/master/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketAwaitableEventArgs.cs
// but without PipeScheduler (always inlining)
internal sealed class SocketAwaitableEventArgs : SocketAsyncEventArgs, ICriticalNotifyCompletion
Copy link
Member

Choose a reason for hiding this comment

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

Do you need this at all? You can use the SocketTask APIs that do this internally. Kestrel only does this because it's trying to schedule directly to the IOQueue from continuations.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The cost of awaiting socket.ReadAsync is quite big, by using this custom class I was able to get +15k RPS. I am going to create an issue in runtime repo

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

@stephentoub stephentoub Apr 10, 2020

Choose a reason for hiding this comment

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

The cost of awaiting socket.ReadAsync is quite big, by using this custom class I was able to get +15k RPS.

"quite big" is ~15K out of ~1065k in a benchmark that's basically seeing how fast it can call this method? To me that's not worth all the extra code and complexity and diverging from how we want developers to use Socket.

I am going to create an issue in runtime repo

Recommending what? If you have concrete ideas for improving it, great, I'd love to see it get faster, but it has to account for a bunch of things you're not here, like the possibility it might be used concurrently, being used via an interface via ValueTask, that there might be a custom SynchronizationContext/TaskScheduler to be used, possible flowing of ExecutionContext, etc.


var array = _array;
var args = _awaitableEventArgs;
args.SetBuffer(new Memory<byte>(array, _length, array.Length - _length));
Copy link
Member

Choose a reason for hiding this comment

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

You should be able to call _socket.ReadAsync here directly instead of using SocketAsyncEventArgs (see https://github.com/dotnet/runtime/blob/e22cf553e11d500c1523034f2c7ff745014e0629/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs#L18).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know, but it's slow. I am going to create an issue in runtime repo

var args = _awaitableEventArgs;
args.SetBuffer(new Memory<byte>(array, _length, array.Length - _length));

if (_socket.ReceiveAsync(args))
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't wait to receive more data if everything hasn't been examined yet. There may be no more data coming.


_offset = 0;

return new ValueTask<FlushResult>(new FlushResult(isCanceled: false, isCompleted: true));
Copy link
Member

Choose a reason for hiding this comment

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

This isCompleted should also only be true if the socket is closed. In Kestrel, we expect PipeWriter.FlushAsync() to never throw. Our transports just log, trip a ConnectionClosed token and return completed FlushResults.

@halter73
Copy link
Member

halter73 commented Apr 9, 2020

I know this isn't a "real" transport, so a lot of my comments are FYI. We can decide how important (or not) they are to address. If this is just to get a sort of upper bound on performance, this is probably fine once we get rid of the extraneous code.

@davidfowl
Copy link
Member

@adamsitnik time to close this?

@adamsitnik adamsitnik closed this Apr 29, 2020
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.

5 participants