Search in sources :

Example 1 with ConnectionState

use of org.apache.bookkeeper.proto.PerChannelBookieClient.ConnectionState in project bookkeeper by apache.

the class TestPerChannelBookieClient method testDisconnectRace.

/**
 * Test that all resources are freed if connections and disconnections
 * are interleaved randomly.
 *
 * {@link https://issues.apache.org/jira/browse/BOOKKEEPER-620}
 */
@Test
public void testDisconnectRace() throws Exception {
    final GenericCallback<PerChannelBookieClient> nullop = new GenericCallback<PerChannelBookieClient>() {

        @Override
        public void operationComplete(int rc, PerChannelBookieClient client) {
        // do nothing, we don't care about doing anything with the connection,
        // we just want to trigger it connecting.
        }
    };
    final int iterations = 100000;
    EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    OrderedExecutor executor = getOrderedSafeExecutor();
    BookieSocketAddress addr = getBookie(0);
    final PerChannelBookieClient client = new PerChannelBookieClient(executor, eventLoopGroup, addr, authProvider, extRegistry);
    final AtomicBoolean shouldFail = new AtomicBoolean(false);
    final AtomicBoolean running = new AtomicBoolean(true);
    final CountDownLatch disconnectRunning = new CountDownLatch(1);
    Thread connectThread = new Thread() {

        public void run() {
            try {
                if (!disconnectRunning.await(10, TimeUnit.SECONDS)) {
                    LOG.error("Disconnect thread never started");
                    shouldFail.set(true);
                }
            } catch (InterruptedException ie) {
                LOG.error("Connect thread interrupted", ie);
                Thread.currentThread().interrupt();
                running.set(false);
            }
            for (int i = 0; i < iterations && running.get(); i++) {
                client.connectIfNeededAndDoOp(nullop);
            }
            running.set(false);
        }
    };
    Thread disconnectThread = new Thread() {

        public void run() {
            disconnectRunning.countDown();
            while (running.get()) {
                client.disconnect();
            }
        }
    };
    Thread checkThread = new Thread() {

        public void run() {
            ConnectionState state;
            Channel channel;
            while (running.get()) {
                synchronized (client) {
                    state = client.state;
                    channel = client.channel;
                    if ((state == ConnectionState.CONNECTED && (channel == null || !channel.isActive())) || (state != ConnectionState.CONNECTED && channel != null && channel.isActive())) {
                        LOG.error("State({}) and channel({}) inconsistent " + channel, state, channel == null ? null : channel.isActive());
                        shouldFail.set(true);
                        running.set(false);
                    }
                }
            }
        }
    };
    connectThread.start();
    disconnectThread.start();
    checkThread.start();
    connectThread.join();
    disconnectThread.join();
    checkThread.join();
    assertFalse("Failure in threads, check logs", shouldFail.get());
    client.close();
    eventLoopGroup.shutdownGracefully();
    executor.shutdown();
}
Also used : Channel(io.netty.channel.Channel) OrderedExecutor(org.apache.bookkeeper.common.util.OrderedExecutor) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) EventLoopGroup(io.netty.channel.EventLoopGroup) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) BookieSocketAddress(org.apache.bookkeeper.net.BookieSocketAddress) ConnectionState(org.apache.bookkeeper.proto.PerChannelBookieClient.ConnectionState) GenericCallback(org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) Test(org.junit.Test)

Aggregations

Channel (io.netty.channel.Channel)1 EventLoopGroup (io.netty.channel.EventLoopGroup)1 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 OrderedExecutor (org.apache.bookkeeper.common.util.OrderedExecutor)1 BookieSocketAddress (org.apache.bookkeeper.net.BookieSocketAddress)1 GenericCallback (org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback)1 ConnectionState (org.apache.bookkeeper.proto.PerChannelBookieClient.ConnectionState)1 Test (org.junit.Test)1