Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
cuteant committed Jul 1, 2021
1 parent c3cc147 commit 2fe1bec
Show file tree
Hide file tree
Showing 16 changed files with 302 additions and 97 deletions.
19 changes: 0 additions & 19 deletions DotNetty.CrossPlatform.sln
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "azure-pipelines", "azure-pi
build\pr-validation.yaml = build\pr-validation.yaml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.NetUV", "src\DotNetty.NetUV\DotNetty.NetUV.csproj", "{3162B002-96BD-4C3A-BA83-94791BA65A49}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "local-build", "local-build", "{D16D7F56-E54C-498D-B4B2-AEBF1C8CA462}"
ProjectSection(SolutionItems) = preProject
DotnetCLIVersion.txt = DotnetCLIVersion.txt
Expand Down Expand Up @@ -284,22 +282,6 @@ Global
{10264C0F-F854-4201-AFCB-2B7315EFBCE0}.Release|x64.Build.0 = Release|Any CPU
{10264C0F-F854-4201-AFCB-2B7315EFBCE0}.Release|x86.ActiveCfg = Release|Any CPU
{10264C0F-F854-4201-AFCB-2B7315EFBCE0}.Release|x86.Build.0 = Release|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|ARM.Build.0 = Debug|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|x64.ActiveCfg = Debug|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|x64.Build.0 = Debug|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|x86.ActiveCfg = Debug|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Debug|x86.Build.0 = Debug|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|Any CPU.Build.0 = Release|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|ARM.ActiveCfg = Release|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|ARM.Build.0 = Release|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|x64.ActiveCfg = Release|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|x64.Build.0 = Release|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|x86.ActiveCfg = Release|Any CPU
{3162B002-96BD-4C3A-BA83-94791BA65A49}.Release|x86.Build.0 = Release|Any CPU
{DA38365F-810D-45FD-A39E-C911FAB8B3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA38365F-810D-45FD-A39E-C911FAB8B3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA38365F-810D-45FD-A39E-C911FAB8B3EB}.Debug|ARM.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -414,7 +396,6 @@ Global
{F5A34D9C-854C-4972-ABF3-8BAE4712386D} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB}
{10264C0F-F854-4201-AFCB-2B7315EFBCE0} = {B6984E67-A4D0-459E-B3C9-01CA4DBBE241}
{EC6681D3-3F9C-4CBB-B5D5-091E7F85D1C7} = {013DFD29-E1DB-4968-A67B-C2342E6F5B6E}
{3162B002-96BD-4C3A-BA83-94791BA65A49} = {3D04C4DC-6F8E-4326-9569-92F3E26C6EEB}
{D16D7F56-E54C-498D-B4B2-AEBF1C8CA462} = {013DFD29-E1DB-4968-A67B-C2342E6F5B6E}
{DA38365F-810D-45FD-A39E-C911FAB8B3EB} = {05F6EB5E-260B-44BC-8B55-E501E1FFB29F}
{D4D133A8-A669-4779-91D0-C80EDA48248E} = {05F6EB5E-260B-44BC-8B55-E501E1FFB29F}
Expand Down
8 changes: 4 additions & 4 deletions examples/Http2Tiles/Html.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ public sealed class Html
+ "<style>body {background:#DDD;} div#netty { line-height:0;}</style>"
+ "<link rel=\"shortcut icon\" href=\"about:blank\">"
+ "<meta charset=\"UTF-8\"></head><body>A grid of 200 tiled images is shown below. Compare:"
+ "<p>[<a href='https://" + Url(Http2Server.PORT) + "?latency=0'>HTTP/2, 0 latency</a>] [<a href='http://"
+ Url(HttpServer.PORT) + "?latency=0'>HTTP/1, 0 latency</a>]<br/>" + "[<a href='https://"
+ "<p>[<a href='http://" + Url(Http2Server.PORT) + "?latency=0'>HTTP/2, 0 latency</a>] [<a href='http://"
+ Url(HttpServer.PORT) + "?latency=0'>HTTP/1, 0 latency</a>]<br/>" + "[<a href='http://"
+ Url(Http2Server.PORT) + "?latency=30'>HTTP/2, 30ms latency</a>] [<a href='http://" + Url(HttpServer.PORT)
+ "?latency=30'>HTTP/1, 30ms latency</a>]<br/>" + "[<a href='https://" + Url(Http2Server.PORT)
+ "?latency=30'>HTTP/1, 30ms latency</a>]<br/>" + "[<a href='http://" + Url(Http2Server.PORT)
+ "?latency=200'>HTTP/2, 200ms latency</a>] [<a href='http://" + Url(HttpServer.PORT)
+ "?latency=200'>HTTP/1, 200ms latency</a>]<br/>" + "[<a href='https://" + Url(Http2Server.PORT)
+ "?latency=200'>HTTP/1, 200ms latency</a>]<br/>" + "[<a href='http://" + Url(Http2Server.PORT)
+ "?latency=1000'>HTTP/2, 1s latency</a>] [<a href='http://" + Url(HttpServer.PORT)
+ "?latency=1000'>HTTP/1, " + "1s latency</a>]<br/>");

Expand Down
23 changes: 14 additions & 9 deletions examples/Http2Tiles/Http2Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,21 @@ public class Http2Server
{
public static readonly int PORT = int.Parse(ExampleHelper.Configuration["http2-port"]);

readonly IEventLoopGroup bossGroup;
readonly IEventLoopGroup workGroup;
readonly IEventLoopGroup _bossGroup;
readonly IEventLoopGroup _workGroup;
readonly bool _ssl;

public Http2Server(IEventLoopGroup bossGroup, IEventLoopGroup workGroup)
public Http2Server(IEventLoopGroup bossGroup, IEventLoopGroup workGroup, bool ssl)
{
this.bossGroup = bossGroup;
this.workGroup = workGroup;
this._bossGroup = bossGroup;
this._workGroup = workGroup;
_ssl = ssl;
}

public Task<IChannel> StartAsync()
{
var bootstrap = new ServerBootstrap();
bootstrap.Group(this.bossGroup, this.workGroup);
bootstrap.Group(this._bossGroup, this._workGroup);

if (ServerSettings.UseLibuv)
{
Expand Down Expand Up @@ -66,14 +68,17 @@ public Task<IChannel> StartAsync()

.ChildHandler(new ActionChannelInitializer<IChannel>(ch =>
{
ch.Pipeline.AddLast(new TlsHandler(new ServerTlsSettings(tlsCertificate)
if (_ssl)
{
ApplicationProtocols = new List<SslApplicationProtocol>(new[]
ch.Pipeline.AddLast(new TlsHandler(new ServerTlsSettings(tlsCertificate)
{
ApplicationProtocols = new List<SslApplicationProtocol>(new[]
{
SslApplicationProtocol.Http2,
SslApplicationProtocol.Http11
})
}));
}));
}
ch.Pipeline.AddLast(new Http2OrHttpHandler());
}));

Expand Down
3 changes: 2 additions & 1 deletion examples/Http2Tiles/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static async Task Main(string[] args)
+ $"\nProcessor Count : {Environment.ProcessorCount}\n");

bool useLibuv = ServerSettings.UseLibuv;
var sslHttp2 = string.Equals(ExampleHelper.Configuration["ssl-http2"], "true", StringComparison.OrdinalIgnoreCase) ? true : false;
Console.WriteLine("Transport type : " + (useLibuv ? "Libuv" : "Socket"));

if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Expand Down Expand Up @@ -62,7 +63,7 @@ static async Task Main(string[] args)

try
{
Http2Server http2 = useLibuv ? new Http2Server(bossGroup2, workGroup2) : new Http2Server(bossGroup, workGroup);
Http2Server http2 = useLibuv ? new Http2Server(bossGroup2, workGroup2, sslHttp2) : new Http2Server(bossGroup, workGroup, sslHttp2);
http2Channel = await http2.StartAsync();

Console.WriteLine("Open your web browser and navigate to " + "http://127.0.0.1:" + HttpServer.PORT);
Expand Down
3 changes: 2 additions & 1 deletion examples/Http2Tiles/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"http-port": "8080",
"http2-port": "8443",
"http2-port": "8090",
"ssl-http2": "false",
"libuv": "true"
}
18 changes: 18 additions & 0 deletions src/DotNetty.Common/Concurrency/AbstractScheduledEventExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ protected AbstractScheduledEventExecutor(IEventExecutorGroup parent)
ScheduledTaskQueue = new DefaultPriorityQueue<IScheduledRunnable>();
}

/// <summary>
/// TBD
/// </summary>
protected abstract bool HasTasks { get; }

[MethodImpl(InlineMethod.AggressiveOptimization)]
protected static PreciseTimeSpan GetNanos() => PreciseTimeSpan.FromStart;

Expand Down Expand Up @@ -493,7 +498,14 @@ private IScheduledRunnable Schedule(IScheduledRunnable task)
{
if (InEventLoop)
{
var isBacklogEmpty = !HasTasks || IsEmpty(ScheduledTaskQueue);
ScheduleFromEventLoop(task);
if (isBacklogEmpty)
{
// 在 Libuv.LoopExecutor 中,当任务执行完毕,清空任务队列后,后续如果只有 ScheduledTask 入队的情况下,
// 并不会激发线程进行任务处理,需唤醒
EnusreWakingUp(true);
}
}
else
{
Expand Down Expand Up @@ -556,6 +568,12 @@ protected virtual bool AfterScheduledTaskSubmitted(long deadlineNanos)
return true;
}

/// <summary>
/// TBD
/// </summary>
/// <param name="inEventLoop"></param>
protected virtual void EnusreWakingUp(bool inEventLoop) { }

sealed class NoOpRunnable : IRunnable
{
public void Run()
Expand Down
6 changes: 2 additions & 4 deletions src/DotNetty.Common/Concurrency/SingleThreadEventExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,8 @@ private SingleThreadEventExecutor(IEventExecutorGroup parent, bool addTaskWakesU
/// </summary>
public int BacklogLength => PendingTasks;

/// <summary>
/// TBD
/// </summary>
protected virtual bool HasTasks => _taskQueue.NonEmpty;
/// <inheritdoc />
protected override bool HasTasks => _taskQueue.NonEmpty;

/// <summary>
/// Gets the number of tasks that are pending for processing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ protected SingleThreadEventExecutorOld(IEventExecutorGroup parent, string thread
/// </summary>
public int BacklogLength => _taskQueue.Count;

/// <inheritdoc />
protected override bool HasTasks => _taskQueue.NonEmpty;

void Loop(object s)
{
SetCurrentExecutor(this);
Expand Down Expand Up @@ -230,7 +233,7 @@ private void AddTask(IRunnable task)

protected override IEnumerable<IEventExecutor> GetItems() => new[] { this };

protected void WakeUp(bool inEventLoop)
protected internal virtual void WakeUp(bool inEventLoop)
{
if (!inEventLoop || (Volatile.Read(ref v_executionState) == ST_SHUTTING_DOWN))
{
Expand Down
44 changes: 30 additions & 14 deletions src/DotNetty.Transport.Libuv/LoopExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
namespace DotNetty.Transport.Libuv
{
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -43,7 +44,9 @@ public abstract class LoopExecutor : SingleThreadEventLoopBase
{
#region @@ Fields @@

private const int DefaultBreakoutTime = 100; //ms
private const long DefaultBreakoutTime = 100L; //ms
private const long MinimumBreakoutTime = 10L; //ms
private const long InfiniteBreakoutTime = 0L; //ms

private static long s_initialTime;
private static long s_startTimeInitialized;
Expand Down Expand Up @@ -123,7 +126,7 @@ private static void Run(object state)
loopExecutor.SetCurrentExecutor(loopExecutor);

_ = Task.Factory.StartNew(
executor => ((LoopExecutor)executor).StartLoop(), state,
static executor => ((LoopExecutor)executor).StartLoop(), state,
CancellationToken.None,
TaskCreationOptions.AttachedToParent,
loopExecutor.Scheduler);
Expand Down Expand Up @@ -237,6 +240,14 @@ protected override void WakeUp(bool inEventLoop)
}
}

protected override void EnusreWakingUp(bool inEventLoop)
{
if (_wakeUp)
{
_ = _timerHandle.Start(MinimumBreakoutTime, 0);
}
}

protected override void OnBeginRunningAllTasks()
{
_wakeUp = false;
Expand All @@ -262,31 +273,36 @@ protected override void AfterRunningAllTasks()
return;
}

long nextTimeout = DefaultBreakoutTime;
var nextTimeout = InfiniteBreakoutTime;
if (HasTasks)
{
_ = _timerHandle.Start(nextTimeout, 0);
nextTimeout = DefaultBreakoutTime;
}
else
else if (ScheduledTaskQueue.TryPeek(out IScheduledRunnable nextScheduledTask))
{
if (ScheduledTaskQueue.TryPeek(out IScheduledRunnable nextScheduledTask))
long delayNanos = nextScheduledTask.DelayNanos;
if ((ulong)delayNanos > 0UL) // delayNanos 为非负值
{
long delayNanos = nextScheduledTask.DelayNanos;
if ((ulong)delayNanos > 0UL) // delayNanos >= 0
{
var timeout = PreciseTime.ToMilliseconds(delayNanos);
nextTimeout = Math.Min(timeout, MaxDelayMilliseconds);
}
_ = _timerHandle.Start(nextTimeout, 0);
var timeout = PreciseTime.ToMilliseconds(delayNanos);
nextTimeout = Math.Min(timeout, MaxDelayMilliseconds);
}
else
{
nextTimeout = MinimumBreakoutTime;
}
}

if ((ulong)nextTimeout > 0UL) // nextTimeout 为非负值
{
_ = _timerHandle.Start(nextTimeout, 0);
}
}

protected override void Run()
{
if (!IsShuttingDown)
{
RunAllTasks(_preciseBreakoutInterval);
_ = RunAllTasks(_preciseBreakoutInterval);
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions src/DotNetty.Transport/Channels/Embedded/EmbeddedEventLoop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ sealed class EmbeddedEventLoop : AbstractScheduledEventExecutor, IEventLoop

public Task RegisterAsync(IChannel channel) => channel.Unsafe.RegisterAsync(this);

protected override bool HasTasks => _tasks.NonEmpty;

public override bool IsShuttingDown => false;

public override Task TerminationCompletion => ThrowHelper.FromNotSupportedException();
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetty.Transport/Channels/VoidChannelPromise.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public VoidChannelPromise(IChannel channel, bool fireException)
if (channel is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.channel); }
_channel = channel;
_fireException = fireException;
_task = new Lazy<Task>(() => TaskUtil.FromException(Error), LazyThreadSafetyMode.ExecutionAndPublication);
_task = new Lazy<Task>(static () => TaskUtil.FromException(Error), LazyThreadSafetyMode.ExecutionAndPublication);
}

public Task Task => _task.Value;
Expand Down
30 changes: 15 additions & 15 deletions test/DotNetty.Codecs.Http2.Tests/Http2ConnectionRoundtripTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,21 @@ public override void StressTest()
}
}

//public sealed class SocketHttp2ConnectionRoundtripTest : AbstractHttp2ConnectionRoundtripTest
//{
// public SocketHttp2ConnectionRoundtripTest(ITestOutputHelper output) : base(output) { }

// protected override void SetupServerBootstrap(ServerBootstrap bootstrap)
// {
// bootstrap.Group(new MultithreadEventLoopGroup(1), new MultithreadEventLoopGroup())
// .Channel<TcpServerSocketChannel>();
// }

// protected override void SetupBootstrap(Bootstrap bootstrap)
// {
// bootstrap.Group(new MultithreadEventLoopGroup()).Channel<TcpSocketChannel>();
// }
//}
public sealed class SocketHttp2ConnectionRoundtripTest : AbstractHttp2ConnectionRoundtripTest
{
public SocketHttp2ConnectionRoundtripTest(ITestOutputHelper output) : base(output) { }

protected override void SetupServerBootstrap(ServerBootstrap bootstrap)
{
bootstrap.Group(new MultithreadEventLoopGroup(1), new MultithreadEventLoopGroup())
.Channel<TcpServerSocketChannel>();
}

protected override void SetupBootstrap(Bootstrap bootstrap)
{
bootstrap.Group(new MultithreadEventLoopGroup()).Channel<TcpSocketChannel>();
}
}

public sealed class LocalHttp2ConnectionRoundtripTest : AbstractHttp2ConnectionRoundtripTest
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,21 @@ protected override void SetupBootstrap(Bootstrap bootstrap)
}
}

//public sealed class SocketHttpToHttp2ConnectionHandlerTest : AbstractHttpToHttp2ConnectionHandlerTest
//{
// public SocketHttpToHttp2ConnectionHandlerTest(ITestOutputHelper output) : base(output) { }

// protected override void SetupServerBootstrap(ServerBootstrap bootstrap)
// {
// bootstrap.Group(new MultithreadEventLoopGroup(1), new MultithreadEventLoopGroup())
// .Channel<TcpServerSocketChannel>();
// }

// protected override void SetupBootstrap(Bootstrap bootstrap)
// {
// bootstrap.Group(new MultithreadEventLoopGroup()).Channel<TcpSocketChannel>();
// }
//}
public sealed class SocketHttpToHttp2ConnectionHandlerTest : AbstractHttpToHttp2ConnectionHandlerTest
{
public SocketHttpToHttp2ConnectionHandlerTest(ITestOutputHelper output) : base(output) { }

protected override void SetupServerBootstrap(ServerBootstrap bootstrap)
{
bootstrap.Group(new MultithreadEventLoopGroup(1), new MultithreadEventLoopGroup())
.Channel<TcpServerSocketChannel>();
}

protected override void SetupBootstrap(Bootstrap bootstrap)
{
bootstrap.Group(new MultithreadEventLoopGroup()).Channel<TcpSocketChannel>();
}
}

public sealed class LocalHttpToHttp2ConnectionHandlerTest : AbstractHttpToHttp2ConnectionHandlerTest
{
Expand Down
Loading

0 comments on commit 2fe1bec

Please sign in to comment.