예제 #1
0
        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));
            }
        }
예제 #2
0
        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));
        }
예제 #3
0
 public void Dispose()
 {
     try
     {
         _group.ShutdownGracefullyAsync();
     }
     catch
     {
         // Ignore RejectedExecutionException(on Azure DevOps)
     }
 }
예제 #4
0
        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));
            }
        }
예제 #5
0
        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));
        }
예제 #6
0
        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));
        }
예제 #7
0
        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));
        }
예제 #8
0
        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));
            }
        }
예제 #9
0
        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));
        }
예제 #10
0
 public void Dispose()
 {
     _group.ShutdownGracefullyAsync();
 }
예제 #11
0
        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());
            }
        }