Search in sources :

Example 1 with DefaultEventLoopGroup

use of io.netty.channel.DefaultEventLoopGroup in project netty by netty.

the class LocalChannelTest method beforeClass.

@BeforeClass
public static void beforeClass() {
    group1 = new DefaultEventLoopGroup(2);
    group2 = new DefaultEventLoopGroup(2);
    sharedGroup = new DefaultEventLoopGroup(1);
}
Also used : DefaultEventLoopGroup(io.netty.channel.DefaultEventLoopGroup) BeforeClass(org.junit.BeforeClass)

Example 2 with DefaultEventLoopGroup

use of io.netty.channel.DefaultEventLoopGroup in project netty by netty.

the class LocalChannelTest method localChannelRaceCondition.

@Test
public void localChannelRaceCondition() throws Exception {
    final CountDownLatch closeLatch = new CountDownLatch(1);
    final EventLoopGroup clientGroup = new DefaultEventLoopGroup(1) {

        @Override
        protected EventLoop newChild(Executor threadFactory, Object... args) throws Exception {
            return new SingleThreadEventLoop(this, threadFactory, true) {

                @Override
                protected void run() {
                    for (; ; ) {
                        Runnable task = takeTask();
                        if (task != null) {
                            /* Only slow down the anonymous class in LocalChannel#doRegister() */
                            if (task.getClass().getEnclosingClass() == LocalChannel.class) {
                                try {
                                    closeLatch.await();
                                } catch (InterruptedException e) {
                                    throw new Error(e);
                                }
                            }
                            task.run();
                            updateLastExecutionTime();
                        }
                        if (confirmShutdown()) {
                            break;
                        }
                    }
                }
            };
        }
    };
    Channel sc = null;
    Channel cc = null;
    try {
        ServerBootstrap sb = new ServerBootstrap();
        sc = sb.group(group2).channel(LocalServerChannel.class).childHandler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) throws Exception {
                ch.close();
                closeLatch.countDown();
            }
        }).bind(TEST_ADDRESS).sync().channel();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(clientGroup).channel(LocalChannel.class).handler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) throws Exception {
            /* Do nothing */
            }
        });
        ChannelFuture future = bootstrap.connect(sc.localAddress());
        assertTrue("Connection should finish, not time out", future.await(200));
        cc = future.channel();
    } finally {
        closeChannel(cc);
        closeChannel(sc);
        clientGroup.shutdownGracefully(0, 0, SECONDS).await();
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) AbstractChannel(io.netty.channel.AbstractChannel) Channel(io.netty.channel.Channel) SingleThreadEventLoop(io.netty.channel.SingleThreadEventLoop) CountDownLatch(java.util.concurrent.CountDownLatch) DefaultEventLoopGroup(io.netty.channel.DefaultEventLoopGroup) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) ConnectException(java.net.ConnectException) ClosedChannelException(java.nio.channels.ClosedChannelException) EventLoopGroup(io.netty.channel.EventLoopGroup) DefaultEventLoopGroup(io.netty.channel.DefaultEventLoopGroup) Executor(java.util.concurrent.Executor) Bootstrap(io.netty.bootstrap.Bootstrap) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) Test(org.junit.Test)

Example 3 with DefaultEventLoopGroup

use of io.netty.channel.DefaultEventLoopGroup in project netty by netty.

the class LocalTransportThreadModelTest method testStagedExecution.

@Test(timeout = 5000)
public void testStagedExecution() throws Throwable {
    EventLoopGroup l = new DefaultEventLoopGroup(4, new DefaultThreadFactory("l"));
    EventExecutorGroup e1 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e1"));
    EventExecutorGroup e2 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e2"));
    ThreadNameAuditor h1 = new ThreadNameAuditor();
    ThreadNameAuditor h2 = new ThreadNameAuditor();
    ThreadNameAuditor h3 = new ThreadNameAuditor(true);
    Channel 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);
    l.register(ch).sync().channel().connect(localAddr).sync();
    // 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().write("5");
    ch.pipeline().context(h3).write("6");
    ch.pipeline().context(h2).write("7");
    ch.pipeline().context(h1).writeAndFlush("8").sync();
    ch.close().sync();
    // Wait until all events are handled completely.
    while (h1.outboundThreadNames.size() < 3 || h3.inboundThreadNames.size() < 3 || h1.removalThreadNames.size() < 1) {
        if (h1.exception.get() != null) {
            throw h1.exception.get();
        }
        if (h2.exception.get() != null) {
            throw h2.exception.get();
        }
        if (h3.exception.get() != null) {
            throw h3.exception.get();
        }
        Thread.sleep(10);
    }
    String currentName = Thread.currentThread().getName();
    try {
        // Events should never be handled from the current thread.
        Assert.assertFalse(h1.inboundThreadNames.contains(currentName));
        Assert.assertFalse(h2.inboundThreadNames.contains(currentName));
        Assert.assertFalse(h3.inboundThreadNames.contains(currentName));
        Assert.assertFalse(h1.outboundThreadNames.contains(currentName));
        Assert.assertFalse(h2.outboundThreadNames.contains(currentName));
        Assert.assertFalse(h3.outboundThreadNames.contains(currentName));
        Assert.assertFalse(h1.removalThreadNames.contains(currentName));
        Assert.assertFalse(h2.removalThreadNames.contains(currentName));
        Assert.assertFalse(h3.removalThreadNames.contains(currentName));
        // Assert that events were handled by the correct executor.
        for (String name : h1.inboundThreadNames) {
            Assert.assertTrue(name.startsWith("l-"));
        }
        for (String name : h2.inboundThreadNames) {
            Assert.assertTrue(name.startsWith("e1-"));
        }
        for (String name : h3.inboundThreadNames) {
            Assert.assertTrue(name.startsWith("e2-"));
        }
        for (String name : h1.outboundThreadNames) {
            Assert.assertTrue(name.startsWith("l-"));
        }
        for (String name : h2.outboundThreadNames) {
            Assert.assertTrue(name.startsWith("e1-"));
        }
        for (String name : h3.outboundThreadNames) {
            Assert.assertTrue(name.startsWith("e2-"));
        }
        for (String name : h1.removalThreadNames) {
            Assert.assertTrue(name.startsWith("l-"));
        }
        for (String name : h2.removalThreadNames) {
            Assert.assertTrue(name.startsWith("e1-"));
        }
        for (String name : h3.removalThreadNames) {
            Assert.assertTrue(name.startsWith("e2-"));
        }
        // Assert that the events for the same handler were handled by the same thread.
        Set<String> names = new HashSet<String>();
        names.addAll(h1.inboundThreadNames);
        names.addAll(h1.outboundThreadNames);
        names.addAll(h1.removalThreadNames);
        Assert.assertEquals(1, names.size());
        names.clear();
        names.addAll(h2.inboundThreadNames);
        names.addAll(h2.outboundThreadNames);
        names.addAll(h2.removalThreadNames);
        Assert.assertEquals(1, names.size());
        names.clear();
        names.addAll(h3.inboundThreadNames);
        names.addAll(h3.outboundThreadNames);
        names.addAll(h3.removalThreadNames);
        Assert.assertEquals(1, names.size());
        // Count the number of events
        Assert.assertEquals(1, h1.inboundThreadNames.size());
        Assert.assertEquals(2, h2.inboundThreadNames.size());
        Assert.assertEquals(3, h3.inboundThreadNames.size());
        Assert.assertEquals(3, h1.outboundThreadNames.size());
        Assert.assertEquals(2, h2.outboundThreadNames.size());
        Assert.assertEquals(1, h3.outboundThreadNames.size());
        Assert.assertEquals(1, h1.removalThreadNames.size());
        Assert.assertEquals(1, h2.removalThreadNames.size());
        Assert.assertEquals(1, h3.removalThreadNames.size());
    } catch (AssertionError e) {
        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 e;
    } finally {
        l.shutdownGracefully();
        e1.shutdownGracefully();
        e2.shutdownGracefully();
        l.terminationFuture().sync();
        e1.terminationFuture().sync();
        e2.terminationFuture().sync();
    }
}
Also used : DefaultThreadFactory(io.netty.util.concurrent.DefaultThreadFactory) DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) EventExecutorGroup(io.netty.util.concurrent.EventExecutorGroup) EventLoopGroup(io.netty.channel.EventLoopGroup) DefaultEventLoopGroup(io.netty.channel.DefaultEventLoopGroup) DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) Channel(io.netty.channel.Channel) DefaultEventLoopGroup(io.netty.channel.DefaultEventLoopGroup) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with DefaultEventLoopGroup

use of io.netty.channel.DefaultEventLoopGroup in project netty by netty.

the class LocalTransportThreadModelTest method init.

@BeforeClass
public static void init() {
    // Configure a test server
    group = new DefaultEventLoopGroup();
    ServerBootstrap sb = new ServerBootstrap();
    sb.group(group).channel(LocalServerChannel.class).childHandler(new ChannelInitializer<LocalChannel>() {

        @Override
        public void initChannel(LocalChannel ch) throws Exception {
            ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {

                @Override
                public void channelRead(ChannelHandlerContext ctx, Object msg) {
                    // Discard
                    ReferenceCountUtil.release(msg);
                }
            });
        }
    });
    localAddr = (LocalAddress) sb.bind(LocalAddress.ANY).syncUninterruptibly().channel().localAddress();
}
Also used : ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) DefaultEventLoopGroup(io.netty.channel.DefaultEventLoopGroup) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) BeforeClass(org.junit.BeforeClass)

Example 5 with DefaultEventLoopGroup

use of io.netty.channel.DefaultEventLoopGroup in project netty by netty.

the class LocalTransportThreadModelTest3 method testConcurrentAddRemove.

private static void testConcurrentAddRemove(boolean inbound) throws Exception {
    EventLoopGroup l = new DefaultEventLoopGroup(4, new DefaultThreadFactory("l"));
    EventExecutorGroup e1 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e1"));
    EventExecutorGroup e2 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e2"));
    EventExecutorGroup e3 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e3"));
    EventExecutorGroup e4 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e4"));
    EventExecutorGroup e5 = new DefaultEventExecutorGroup(4, new DefaultThreadFactory("e5"));
    final EventExecutorGroup[] groups = { e1, e2, e3, e4, e5 };
    try {
        Deque<EventType> events = new ConcurrentLinkedDeque<EventType>();
        final EventForwarder h1 = new EventForwarder();
        final EventForwarder h2 = new EventForwarder();
        final EventForwarder h3 = new EventForwarder();
        final EventForwarder h4 = new EventForwarder();
        final EventForwarder h5 = new EventForwarder();
        final EventRecorder h6 = new EventRecorder(events, inbound);
        final Channel ch = new LocalChannel();
        if (!inbound) {
            ch.config().setAutoRead(false);
        }
        ch.pipeline().addLast(e1, h1).addLast(e1, h2).addLast(e1, h3).addLast(e1, h4).addLast(e1, h5).addLast(e1, "recorder", h6);
        l.register(ch).sync().channel().connect(localAddr).sync();
        final LinkedList<EventType> expectedEvents = events(inbound, 8192);
        Throwable cause = new Throwable();
        Thread pipelineModifier = new Thread(new Runnable() {

            @Override
            public void run() {
                Random random = new Random();
                while (true) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        return;
                    }
                    if (!ch.isRegistered()) {
                        continue;
                    }
                    //EventForwardHandler forwardHandler = forwarders[random.nextInt(forwarders.length)];
                    ChannelHandler handler = ch.pipeline().removeFirst();
                    ch.pipeline().addBefore(groups[random.nextInt(groups.length)], "recorder", UUID.randomUUID().toString(), handler);
                }
            }
        });
        pipelineModifier.setDaemon(true);
        pipelineModifier.start();
        for (EventType event : expectedEvents) {
            switch(event) {
                case EXCEPTION_CAUGHT:
                    ch.pipeline().fireExceptionCaught(cause);
                    break;
                case MESSAGE_RECEIVED:
                    ch.pipeline().fireChannelRead("");
                    break;
                case MESSAGE_RECEIVED_LAST:
                    ch.pipeline().fireChannelReadComplete();
                    break;
                case USER_EVENT:
                    ch.pipeline().fireUserEventTriggered("");
                    break;
                case WRITE:
                    ch.pipeline().write("");
                    break;
                case READ:
                    ch.pipeline().read();
                    break;
            }
        }
        ch.close().sync();
        while (events.peekLast() != EventType.UNREGISTERED) {
            Thread.sleep(10);
        }
        expectedEvents.addFirst(EventType.ACTIVE);
        expectedEvents.addFirst(EventType.REGISTERED);
        expectedEvents.addLast(EventType.INACTIVE);
        expectedEvents.addLast(EventType.UNREGISTERED);
        for (; ; ) {
            EventType event = events.poll();
            if (event == null) {
                Assert.assertTrue("Missing events:" + expectedEvents, expectedEvents.isEmpty());
                break;
            }
            Assert.assertEquals(event, expectedEvents.poll());
        }
    } finally {
        l.shutdownGracefully();
        e1.shutdownGracefully();
        e2.shutdownGracefully();
        e3.shutdownGracefully();
        e4.shutdownGracefully();
        e5.shutdownGracefully();
        l.terminationFuture().sync();
        e1.terminationFuture().sync();
        e2.terminationFuture().sync();
        e3.terminationFuture().sync();
        e4.terminationFuture().sync();
        e5.terminationFuture().sync();
    }
}
Also used : DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) EventExecutorGroup(io.netty.util.concurrent.EventExecutorGroup) DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) Channel(io.netty.channel.Channel) ChannelHandler(io.netty.channel.ChannelHandler) DefaultEventLoopGroup(io.netty.channel.DefaultEventLoopGroup) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) DefaultThreadFactory(io.netty.util.concurrent.DefaultThreadFactory) EventLoopGroup(io.netty.channel.EventLoopGroup) DefaultEventLoopGroup(io.netty.channel.DefaultEventLoopGroup) Random(java.util.Random)

Aggregations

DefaultEventLoopGroup (io.netty.channel.DefaultEventLoopGroup)17 Channel (io.netty.channel.Channel)14 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)12 Bootstrap (io.netty.bootstrap.Bootstrap)10 EventLoopGroup (io.netty.channel.EventLoopGroup)9 LocalAddress (io.netty.channel.local.LocalAddress)9 LocalChannel (io.netty.channel.local.LocalChannel)9 LocalServerChannel (io.netty.channel.local.LocalServerChannel)9 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)8 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)7 Test (org.junit.Test)7 ChannelFuture (io.netty.channel.ChannelFuture)6 CountDownLatch (java.util.concurrent.CountDownLatch)5 ChannelHandler (io.netty.channel.ChannelHandler)3 ChannelPipeline (io.netty.channel.ChannelPipeline)3 DefaultEventExecutorGroup (io.netty.util.concurrent.DefaultEventExecutorGroup)3 DefaultThreadFactory (io.netty.util.concurrent.DefaultThreadFactory)3 EventExecutorGroup (io.netty.util.concurrent.EventExecutorGroup)3 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)2 LocalEventLoopGroup (io.netty.channel.local.LocalEventLoopGroup)2