Search in sources :

Example 1 with EventExecutorGroup

use of io.netty.util.concurrent.EventExecutorGroup 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 2 with EventExecutorGroup

use of io.netty.util.concurrent.EventExecutorGroup 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)

Example 3 with EventExecutorGroup

use of io.netty.util.concurrent.EventExecutorGroup in project netty by netty.

the class DefaultChannelPipelineTest method testPinExecutor.

@Test
public void testPinExecutor() {
    EventExecutorGroup group = new DefaultEventExecutorGroup(2);
    ChannelPipeline pipeline = new LocalChannel().pipeline();
    ChannelPipeline pipeline2 = new LocalChannel().pipeline();
    pipeline.addLast(group, "h1", new ChannelInboundHandlerAdapter());
    pipeline.addLast(group, "h2", new ChannelInboundHandlerAdapter());
    pipeline2.addLast(group, "h3", new ChannelInboundHandlerAdapter());
    EventExecutor executor1 = pipeline.context("h1").executor();
    EventExecutor executor2 = pipeline.context("h2").executor();
    assertNotNull(executor1);
    assertNotNull(executor2);
    assertSame(executor1, executor2);
    EventExecutor executor3 = pipeline2.context("h3").executor();
    assertNotNull(executor3);
    assertNotSame(executor3, executor2);
    group.shutdownGracefully(0, 0, TimeUnit.SECONDS);
}
Also used : DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) EventExecutorGroup(io.netty.util.concurrent.EventExecutorGroup) EventExecutor(io.netty.util.concurrent.EventExecutor) AbstractEventExecutor(io.netty.util.concurrent.AbstractEventExecutor) ImmediateEventExecutor(io.netty.util.concurrent.ImmediateEventExecutor) UnorderedThreadPoolEventExecutor(io.netty.util.concurrent.UnorderedThreadPoolEventExecutor) DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) LocalChannel(io.netty.channel.local.LocalChannel) Test(org.junit.Test)

Example 4 with EventExecutorGroup

use of io.netty.util.concurrent.EventExecutorGroup in project netty by netty.

the class DefaultChannelPipelineTest method testHandlerAddedExceptionFromChildHandlerIsPropegated.

@Test(timeout = 3000)
public void testHandlerAddedExceptionFromChildHandlerIsPropegated() {
    final EventExecutorGroup group1 = new DefaultEventExecutorGroup(1);
    try {
        final Promise<Void> promise = group1.next().newPromise();
        final AtomicBoolean handlerAdded = new AtomicBoolean();
        final Exception exception = new RuntimeException();
        ChannelPipeline pipeline = new LocalChannel().pipeline();
        pipeline.addLast(group1, new CheckExceptionHandler(exception, promise));
        pipeline.addFirst(new ChannelHandlerAdapter() {

            @Override
            public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
                handlerAdded.set(true);
                throw exception;
            }
        });
        assertFalse(handlerAdded.get());
        group.register(pipeline.channel());
        promise.syncUninterruptibly();
    } finally {
        group1.shutdownGracefully();
    }
}
Also used : DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) EventExecutorGroup(io.netty.util.concurrent.EventExecutorGroup) DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) LocalChannel(io.netty.channel.local.LocalChannel) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Test(org.junit.Test)

Example 5 with EventExecutorGroup

use of io.netty.util.concurrent.EventExecutorGroup in project netty by netty.

the class DefaultChannelPipelineTest method testHandlerRemovedExceptionFromChildHandlerIsPropegated.

@Test(timeout = 3000)
public void testHandlerRemovedExceptionFromChildHandlerIsPropegated() {
    final EventExecutorGroup group1 = new DefaultEventExecutorGroup(1);
    try {
        final Promise<Void> promise = group1.next().newPromise();
        String handlerName = "foo";
        final Exception exception = new RuntimeException();
        ChannelPipeline pipeline = new LocalChannel().pipeline();
        pipeline.addLast(handlerName, new ChannelHandlerAdapter() {

            @Override
            public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
                throw exception;
            }
        });
        pipeline.addLast(group1, new CheckExceptionHandler(exception, promise));
        group.register(pipeline.channel()).syncUninterruptibly();
        pipeline.remove(handlerName);
        promise.syncUninterruptibly();
    } finally {
        group1.shutdownGracefully();
    }
}
Also used : DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) EventExecutorGroup(io.netty.util.concurrent.EventExecutorGroup) DefaultEventExecutorGroup(io.netty.util.concurrent.DefaultEventExecutorGroup) LocalChannel(io.netty.channel.local.LocalChannel) Test(org.junit.Test)

Aggregations

EventExecutorGroup (io.netty.util.concurrent.EventExecutorGroup)17 DefaultEventExecutorGroup (io.netty.util.concurrent.DefaultEventExecutorGroup)13 Test (org.junit.Test)10 LocalChannel (io.netty.channel.local.LocalChannel)7 Channel (io.netty.channel.Channel)5 EventLoopGroup (io.netty.channel.EventLoopGroup)4 EventExecutor (io.netty.util.concurrent.EventExecutor)4 ChannelHandler (io.netty.channel.ChannelHandler)3 ChannelPipeline (io.netty.channel.ChannelPipeline)3 DefaultEventLoopGroup (io.netty.channel.DefaultEventLoopGroup)3 SocketChannel (io.netty.channel.socket.SocketChannel)3 SslHandler (io.netty.handler.ssl.SslHandler)3 DefaultThreadFactory (io.netty.util.concurrent.DefaultThreadFactory)3 UnorderedThreadPoolEventExecutor (io.netty.util.concurrent.UnorderedThreadPoolEventExecutor)3 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)2 ChannelFuture (io.netty.channel.ChannelFuture)2 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)2 NioServerSocketChannel (io.netty.channel.socket.nio.NioServerSocketChannel)2 AbstractEventExecutor (io.netty.util.concurrent.AbstractEventExecutor)2 ImmediateEventExecutor (io.netty.util.concurrent.ImmediateEventExecutor)2