Skip to content
Linux Transport for Kestrel
C#
Branch: master
Clone or download
Latest commit ba40817 Nov 13, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
externals
samples Update for ASP.NET Core 3.0 compat (#80) Sep 10, 2019
src/RedHat.AspNetCore.Server.Kestrel.Transport.Linux
test
.gitignore Add sln (#72) Dec 4, 2018
.travis.yml Use released 3.0.100 sdk (#89) Oct 24, 2019
Benchmark.md Benchmark.md: describe how to benchmark Apr 19, 2017
LICENSE
NuGet.config Use Tmds.LibC 0.1.0 from nuget.org Feb 4, 2019
README.md Update README.md (#93) Nov 5, 2019
RedHat.AspNetCore.Server.Kestrel.Transport.sln Add sln (#72) Dec 4, 2018
THIRD-PARTY-NOTICES.txt Update for ASP.NET Core 3.0 compat (#80) Sep 10, 2019
dependencies.props
global.json

README.md

Travis

Introduction

The ASP.NET Core Kestrel webserver has been using libuv as a cross-platform network library. It is possible to replace libuv with another implementation thanks to the Transport abstraction.

In this repo we explore creating a Transport for Linux specifically.

Using the package

Add the myget feed to your NuGet.Config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="rh" value="https://www.myget.org/F/redhat-dotnet/api/v3/index.json" />
  </packageSources>
</configuration>

Include a package reference in your project csproj file:

  <ItemGroup>
    <PackageReference Include="RedHat.AspNetCore.Server.Kestrel.Transport.Linux" Version="3.0.0-*" />
  </ItemGroup>

Call UseLinuxTransport when creating the WebHost in your Program.cs:

public static IWebHost BuildWebHost(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder
                        .UseLinuxTransport()
                        .UseStartup<Startup>();
                });

note: It's safe to call UseLinuxTransport on non-Linux platforms, it will no-op.

Repo structure

There are 5 projects in this repository:

  • src/RedHat.AspNetCore.Server.Kestrel.Transport.Linux: managed library implementing Transport
  • samples/KestrelSample: Kestrel app for benchmarking
  • test/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.Test: xunit test projects, has access to internals of managed library
  • test/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.TestApp: empty application to use during development, has access to internals of managed library

The library can be packaged by running the dotnet pack on src/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.

$ dotnet pack src/RedHat.AspNetCore.Server.Kestrel.Transport.Linux --configuration Release

To build the library and run the tests execute dotnet test on test/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.Test.

$ dotnet test test/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.Test

Design

Similar to other implementations, this library makes use of the non-blocking socket and epoll. Like the corefx Socket implementation, the eventloop is implemented in managed (C#) code. This is different from the libuv loop which is part of the native libuv library.

This library does not provide a generic xplat network API. It uses the kernel primitives directly to implement the Transport API. This reduces the number of heap allocated objects (e.g. uv_buf_t, SocketAsyncEventArgs), which means there is less GC pressure. Implementations building on top of an xplat API will pool objects to achieve this.

The implementation starts a number of threads that each accept connections. This is based on SO_REUSEPORT socket option. This option allow multiple sockets to concurrently bind and listen to the same port. The kernel performs load-balancing between the listen sockets.

The Transport has these options:

  • DeferSend: This defers sends to the Transport Thread which increases chances for multiple sends to coalesce. This options defaults to true.

  • ThreadCount: Specifies the number of Transport Threads. This defaults to the number of logical processors in the system, maxed to 16.

  • AioSend/AioReceive: Uses Linux AIO system calls to batch send and receive calls. AioSend implies DeferSend. These options default to true.

You can’t perform that action at this time.