public async Task TestClosedChannelExceptionCarryIOException() { IOException ioException = new IOException(); IChannel channel = new TestChannel0(ioException); var loopGroup = new DefaultEventLoopGroup(1); IEventLoop loop = loopGroup.GetNext(); try { RegisterChannel(loop, channel); await channel.ConnectAsync(new IPEndPoint(IPAddress.IPv6Any, 8888)); try { await channel.WriteAndFlushAsync(""); } catch (Exception exc) { Assert.Same(ioException, exc); } AssertClosedChannelException(channel.WriteAndFlushAsync(""), ioException); AssertClosedChannelException(channel.WriteAsync(""), ioException); AssertClosedChannelException(channel.BindAsync(new IPEndPoint(IPAddress.IPv6Any, 8888)), ioException); } finally { channel.CloseAsync().Ignore(); await loopGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)); } }
public async Task TestAcquire() { var group = new DefaultEventLoopGroup(); var addr = new LocalAddress(ChannelPoolTestUtils.GetLocalAddrId()); var cb = new Bootstrap().RemoteAddress(addr).Group(group).Channel <LocalChannel>(); var sb = new ServerBootstrap() .Group(group) .Channel <LocalServerChannel>() .ChildHandler( new ActionChannelInitializer <LocalChannel>( ch => ch.Pipeline.AddLast(new ChannelHandlerAdapter())) ); // Start server IChannel sc = await sb.BindAsync(addr); var handler = new CountingChannelPoolHandler(); var pool = new SimpleChannelPool(cb, handler); IChannel channel = await pool.AcquireAsync(); await pool.ReleaseAsync(channel); IChannel channel2 = await pool.AcquireAsync(); Assert.Same(channel, channel2); Assert.Equal(1, handler.ChannelCount); await pool.ReleaseAsync(channel2); // Should fail on multiple release calls. await Assert.ThrowsAsync <ArgumentException>(async() => await pool.ReleaseAsync(channel2)); Assert.False(channel.IsActive); try { await pool.ReleaseAsync(channel2); Assert.True(false, "release should fail"); } catch (ArgumentException) { // expected Assert.False(channel.IsActive); } Assert.Equal(1, handler.AcquiredCount); Assert.Equal(2, handler.ReleasedCount); await sc.CloseAsync(); pool.Close(); await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)); }
public void Dispose() { try { _group.ShutdownGracefullyAsync(); } catch { // Ignore RejectedExecutionException(on Azure DevOps) } }
private static async Task TestParentHandler0(bool channelInitializer) { LocalAddress addr = new LocalAddress(Guid.NewGuid().ToString()); CountdownEvent readLatch = new CountdownEvent(1); CountdownEvent initLatch = new CountdownEvent(1); IChannelHandler handler = new TestHandler(readLatch, initLatch); IEventLoopGroup group = new DefaultEventLoopGroup(1); IChannel sch = null; IChannel cch = null; try { ServerBootstrap sb = new ServerBootstrap(); sb.Channel <LocalServerChannel>() .Group(group) .ChildHandler(new ChannelHandlerAdapter()); if (channelInitializer) { sb.Handler(new ActionChannelInitializer <IChannel>(ch => ch.Pipeline.AddLast(handler))); } else { sb.Handler(handler); } Bootstrap cb = new Bootstrap(); cb.Group(group) .Channel <LocalChannel>() .Handler(new ChannelHandlerAdapter()); sch = await sb.BindAsync(addr); cch = await cb.ConnectAsync(addr); initLatch.Wait(); readLatch.Wait(); } finally { if (sch != null) { await sch.CloseAsync(); } if (cch != null) { await cch.CloseAsync(); } await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)); } }
public async Task TestBoundedChannelPoolSegment() { var group = new DefaultEventLoopGroup(); var addr = new LocalAddress(ChannelPoolTestUtils.GetLocalAddrId()); Bootstrap cb = new Bootstrap().RemoteAddress(addr).Group(group).Channel <LocalChannel>(); ServerBootstrap sb = new ServerBootstrap() .Group(group) .Channel <LocalServerChannel>() .ChildHandler( new ActionChannelInitializer <LocalChannel>( ch => ch.Pipeline.AddLast(new ChannelHandlerAdapter())) ); // Start server IChannel sc = await sb.BindAsync(addr); var handler = new CountingChannelPoolHandler(); var pool = new SingleChannelPool(cb, handler); IChannel channel = await pool.AcquireAsync(); IChannel channel2 = await pool.AcquireAsync(); await pool.ReleaseAsync(channel); await Assert.ThrowsAsync <InvalidOperationException>(async() => await pool.ReleaseAsync(channel2)); await channel2.CloseAsync(); Assert.Equal(2, handler.ChannelCount); Assert.Equal(0, handler.AcquiredCount); Assert.Equal(1, handler.ReleasedCount); await sc.CloseAsync(); await channel.CloseAsync(); await channel2.CloseAsync(); pool.Close(); await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)); }
public async Task TestUnhealthyChannelIsNotOffered() { var group = new DefaultEventLoopGroup(); var addr = new LocalAddress(ChannelPoolTestUtils.GetLocalAddrId()); Bootstrap cb = new Bootstrap().RemoteAddress(addr).Group(group).Channel <LocalChannel>(); ServerBootstrap sb = new ServerBootstrap() .Group(group) .Channel <LocalServerChannel>() .ChildHandler( new ActionChannelInitializer <LocalChannel>( ch => ch.Pipeline.AddLast(new ChannelHandlerAdapter())) ); // Start server IChannel sc = await sb.BindAsync(addr); var handler = new CountingChannelPoolHandler(); var pool = new SimpleChannelPool(cb, handler); IChannel channel1 = await pool.AcquireAsync(); await pool.ReleaseAsync(channel1); IChannel channel2 = await pool.AcquireAsync(); //first check that when returned healthy then it actually offered back to the pool. Assert.Same(channel1, channel2); await channel1.CloseAsync(); await pool.ReleaseAsync(channel1); IChannel channel3 = await pool.AcquireAsync(); //channel1 was not healthy anymore so it should not get acquired anymore. Assert.NotSame(channel1, channel3); await sc.CloseAsync(); await channel3.CloseAsync(); pool.Close(); await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)); }
public async Task TestCloseAsync() { var group = new DefaultEventLoopGroup(); var addr = new LocalAddress(ChannelPoolTestUtils.GetLocalAddrId()); Bootstrap cb = new Bootstrap().RemoteAddress(addr).Group(group).Channel <LocalChannel>(); ServerBootstrap sb = new ServerBootstrap() .Group(group) .Channel <LocalServerChannel>() .ChildHandler( new ActionChannelInitializer <LocalChannel>( ch => ch.Pipeline.AddLast(new ChannelHandlerAdapter())) ); // Start server IChannel sc = await sb.BindAsync(addr); var handler = new CountingChannelPoolHandler(); var pool = new SimpleChannelPool(cb, handler); var ch1 = await pool.AcquireAsync(); var ch2 = await pool.AcquireAsync(); pool.ReleaseAsync(ch1).Wait(TimeSpan.FromSeconds(1)); pool.ReleaseAsync(ch2).Wait(TimeSpan.FromSeconds(1)); // Assert that returned channels are open before close Assert.True(ch1.IsOpen); Assert.True(ch2.IsOpen); // Close asynchronously with timeout await pool.CloseAsync().WithTimeout(TimeSpan.FromSeconds(1)); // Assert channels were indeed closed Assert.False(ch1.IsOpen); Assert.False(ch2.IsOpen); await sc.CloseAsync(); pool.Close(); await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)); }
public async Task TestHandlerRegister() { CountdownEvent latch = new CountdownEvent(1); AtomicReference <Exception> error = new AtomicReference <Exception>(); var group = new DefaultEventLoopGroup(1); try { ServerBootstrap sb = new ServerBootstrap(); sb.Channel <LocalServerChannel>() .Group(group) .ChildHandler(new ChannelHandlerAdapter()) .Handler(new TestRegisterHandler(latch, error)); await sb.RegisterAsync(); latch.Wait(); Assert.Null(error.Value); } finally { await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)); } }
public async Task TestUnhealthyChannelIsOfferedWhenNoHealthCheckRequested() { var group = new DefaultEventLoopGroup(); var addr = new LocalAddress(ChannelPoolTestUtils.GetLocalAddrId()); Bootstrap cb = new Bootstrap().RemoteAddress(addr).Group(group).Channel <LocalChannel>(); ServerBootstrap sb = new ServerBootstrap() .Group(group) .Channel <LocalServerChannel>() .ChildHandler( new ActionChannelInitializer <LocalChannel>( ch => ch.Pipeline.AddLast(new ChannelHandlerAdapter())) ); // Start server IChannel sc = await sb.BindAsync(addr); var handler = new CountingChannelPoolHandler(); var pool = new SimpleChannelPool(cb, handler, ChannelActiveHealthChecker.Instance, false); IChannel channel1 = await pool.AcquireAsync(); await channel1.CloseAsync(); await pool.ReleaseAsync(channel1); IChannel channel2 = await pool.AcquireAsync(); //verifying that in fact the channel2 is different that means is not pulled from the pool Assert.NotSame(channel1, channel2); await sc.CloseAsync(); await channel2.CloseAsync(); pool.Close(); await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)); }
public void Dispose() { _group.ShutdownGracefullyAsync(); }
public async Task TestStagedExecution() { IEventLoopGroup l = new DefaultEventLoopGroup(4, new DefaultThreadFactory("l")); IEventExecutorGroup e1 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e1")); IEventExecutorGroup e2 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e2")); ThreadNameAuditor h1 = new ThreadNameAuditor(); ThreadNameAuditor h2 = new ThreadNameAuditor(); ThreadNameAuditor h3 = new ThreadNameAuditor(true); IChannel ch = new LocalChannel(); // With no EventExecutor specified, h1 will be always invoked by EventLoop 'l'. ch.Pipeline.AddLast(h1); // h2 will be always invoked by EventExecutor 'e1'. ch.Pipeline.AddLast(e1, h2); // h3 will be always invoked by EventExecutor 'e2'. ch.Pipeline.AddLast(e2, h3); await l.RegisterAsync(ch); await ch.ConnectAsync(_localAddr); // Fire inbound events from all possible starting points. ch.Pipeline.FireChannelRead("1"); ch.Pipeline.Context(h1).FireChannelRead("2"); ch.Pipeline.Context(h2).FireChannelRead("3"); ch.Pipeline.Context(h3).FireChannelRead("4"); // Fire outbound events from all possible starting points. ch.Pipeline.WriteAsync("5").Ignore(); ch.Pipeline.Context(h3).WriteAsync("6").Ignore(); ch.Pipeline.Context(h2).WriteAsync("7").Ignore(); await ch.Pipeline.Context(h1).WriteAndFlushAsync("8"); await ch.CloseAsync(); // Wait until all events are handled completely. while (h1._outboundThreadNames.Count < 3 || h3._inboundThreadNames.Count < 3 || h1._removalThreadNames.Count < 1) { if (h1._exception.Value != null) { throw h1._exception.Value; } if (h2._exception.Value != null) { throw h2._exception.Value; } if (h3._exception.Value != null) { throw h3._exception.Value; } Thread.Sleep(10); } string currentName = Thread.CurrentThread.Name; try { // Events should never be handled from the current thread. Assert.DoesNotContain(currentName, h1._inboundThreadNames); Assert.DoesNotContain(currentName, h2._inboundThreadNames); Assert.DoesNotContain(currentName, h3._inboundThreadNames); Assert.DoesNotContain(currentName, h1._outboundThreadNames); Assert.DoesNotContain(currentName, h2._outboundThreadNames); Assert.DoesNotContain(currentName, h3._outboundThreadNames); Assert.DoesNotContain(currentName, h1._removalThreadNames); Assert.DoesNotContain(currentName, h2._removalThreadNames); Assert.DoesNotContain(currentName, h3._removalThreadNames); // Assert that events were handled by the correct executor. foreach (string name in h1._inboundThreadNames) { Assert.StartsWith("l-", name); } foreach (string name in h2._inboundThreadNames) { Assert.StartsWith("e1-", name); } foreach (string name in h3._inboundThreadNames) { Assert.StartsWith("e2-", name); } foreach (string name in h1._outboundThreadNames) { Assert.StartsWith("l-", name); } foreach (string name in h2._outboundThreadNames) { Assert.StartsWith("e1-", name); } foreach (string name in h3._outboundThreadNames) { Assert.StartsWith("e2-", name); } foreach (string name in h1._removalThreadNames) { Assert.StartsWith("l-", name); } foreach (string name in h2._removalThreadNames) { Assert.StartsWith("e1-", name); } foreach (string name in h3._removalThreadNames) { Assert.StartsWith("e2-", name); } // Assert that the events for the same handler were handled by the same thread. HashSet <string> names = new HashSet <string>(); names.UnionWith(h1._inboundThreadNames); names.UnionWith(h1._outboundThreadNames); names.UnionWith(h1._removalThreadNames); Assert.Single(names); names.Clear(); names.UnionWith(h2._inboundThreadNames); names.UnionWith(h2._outboundThreadNames); names.UnionWith(h2._removalThreadNames); Assert.Single(names); names.Clear(); names.UnionWith(h3._inboundThreadNames); names.UnionWith(h3._outboundThreadNames); names.UnionWith(h3._removalThreadNames); Assert.Single(names); // Count the number of events Assert.Single(h1._inboundThreadNames); Assert.Equal(2, h2._inboundThreadNames.Count); Assert.Equal(3, h3._inboundThreadNames.Count); Assert.Equal(3, h1._outboundThreadNames.Count); Assert.Equal(2, h2._outboundThreadNames.Count); Assert.Single(h3._outboundThreadNames); Assert.Single(h1._removalThreadNames); Assert.Single(h2._removalThreadNames); Assert.Single(h3._removalThreadNames); } catch (Exception) { //System.out.println("H1I: " + h1.inboundThreadNames); //System.out.println("H2I: " + h2.inboundThreadNames); //System.out.println("H3I: " + h3.inboundThreadNames); //System.out.println("H1O: " + h1.outboundThreadNames); //System.out.println("H2O: " + h2.outboundThreadNames); //System.out.println("H3O: " + h3.outboundThreadNames); //System.out.println("H1R: " + h1.removalThreadNames); //System.out.println("H2R: " + h2.removalThreadNames); //System.out.println("H3R: " + h3.removalThreadNames); throw; } finally { Task.WaitAll( l.ShutdownGracefullyAsync(), e1.ShutdownGracefullyAsync(), e2.ShutdownGracefullyAsync()); } }