Search in sources :

Example 1 with PooledConnection

use of reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection in project reactor-netty by reactor.

the class DefaultPooledConnectionProviderTest method fixedPoolTwoAcquire.

@Test
void fixedPoolTwoAcquire() throws Exception {
    final ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
    int echoServerPort = SocketUtils.findAvailableTcpPort();
    TcpClientTests.EchoServer echoServer = new TcpClientTests.EchoServer(echoServerPort);
    EventLoopGroup group = new NioEventLoopGroup(2);
    java.util.concurrent.Future<?> f1 = null;
    java.util.concurrent.Future<?> f2 = null;
    Future<?> sf = null;
    try (AddressResolverGroup<?> resolver = NameResolverProvider.builder().build().newNameResolverGroup(TcpResources.get(), true)) {
        final InetSocketAddress address = InetSocketAddress.createUnresolved("localhost", echoServerPort);
        ConnectionProvider pool = ConnectionProvider.create("fixedPoolTwoAcquire", 2);
        Supplier<? extends SocketAddress> remoteAddress = () -> address;
        ConnectionObserver observer = ConnectionObserver.emptyListener();
        ClientTransportConfigImpl config = new ClientTransportConfigImpl(group, pool, Collections.emptyMap(), remoteAddress, resolver);
        // fail a couple
        StepVerifier.create(pool.acquire(config, observer, remoteAddress, config.resolverInternal())).verifyErrorMatches(msg -> msg.getCause() instanceof ConnectException);
        StepVerifier.create(pool.acquire(config, observer, remoteAddress, config.resolverInternal())).verifyErrorMatches(msg -> msg.getCause() instanceof ConnectException);
        // start the echo server
        f1 = service.submit(echoServer);
        Thread.sleep(100);
        // acquire 2
        final PooledConnection c1 = (PooledConnection) pool.acquire(config, observer, remoteAddress, config.resolverInternal()).block(Duration.ofSeconds(30));
        assertThat(c1).isNotNull();
        final PooledConnection c2 = (PooledConnection) pool.acquire(config, observer, remoteAddress, config.resolverInternal()).block(Duration.ofSeconds(30));
        assertThat(c2).isNotNull();
        // make room for 1 more
        c2.disposeNow();
        final PooledConnection c3 = (PooledConnection) pool.acquire(config, observer, remoteAddress, config.resolverInternal()).block(Duration.ofSeconds(30));
        assertThat(c3).isNotNull();
        // next one will block until a previous one is released
        long start = System.currentTimeMillis();
        sf = service.schedule(() -> c1.onStateChange(c1, ConnectionObserver.State.DISCONNECTING), 500, TimeUnit.MILLISECONDS);
        final PooledConnection c4 = (PooledConnection) pool.acquire(config, observer, remoteAddress, config.resolverInternal()).block(Duration.ofSeconds(30));
        assertThat(c4).isNotNull();
        long end = System.currentTimeMillis();
        assertThat(end - start).as("channel4 acquire blocked until channel1 released").isGreaterThanOrEqualTo(500);
        c3.onStateChange(c3, ConnectionObserver.State.DISCONNECTING);
        c4.onStateChange(c4, ConnectionObserver.State.DISCONNECTING);
        assertThat(c1).isEqualTo(c4);
        assertThat(c1.pool).isEqualTo(c2.pool).isEqualTo(c3.pool).isEqualTo(c4.pool);
        InstrumentedPool<PooledConnection> defaultPool = c1.pool;
        CountDownLatch latch = new CountDownLatch(1);
        f2 = service.submit(() -> {
            while (defaultPool.metrics().acquiredSize() > 0) {
                LockSupport.parkNanos(100);
            }
            latch.countDown();
        });
        assertThat(latch.await(5, TimeUnit.SECONDS)).as("activeConnections fully released").isTrue();
    } finally {
        service.shutdownNow();
        echoServer.close();
        group.shutdownGracefully().get(5, TimeUnit.SECONDS);
        assertThat(f1).isNotNull();
        assertThat(f1.get()).isNull();
        assertThat(f2).isNotNull();
        assertThat(f2.get()).isNull();
        assertThat(sf).isNotNull();
        assertThat(sf.get()).isNull();
    }
}
Also used : ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) TcpClientTests(reactor.netty.tcp.TcpClientTests) InetSocketAddress(java.net.InetSocketAddress) CountDownLatch(java.util.concurrent.CountDownLatch) ConnectionObserver(reactor.netty.ConnectionObserver) PooledConnection(reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) EventLoopGroup(io.netty.channel.EventLoopGroup) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) ConnectException(java.net.ConnectException) Test(org.junit.jupiter.api.Test)

Example 2 with PooledConnection

use of reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection in project reactor-netty by reactor.

the class DefaultPooledConnectionProviderTest method testIssue673_TimeoutException.

@Test
void testIssue673_TimeoutException() throws InterruptedException {
    DisposableServer server = TcpServer.create().port(0).handle((in, out) -> out.sendString(Mono.just("test").delayElement(Duration.ofMillis(100)))).wiretap(true).bindNow();
    DefaultPooledConnectionProvider provider = (DefaultPooledConnectionProvider) ConnectionProvider.builder("testIssue673_TimeoutException").maxConnections(1).pendingAcquireMaxCount(4).pendingAcquireTimeout(Duration.ofMillis(10)).build();
    CountDownLatch latch = new CountDownLatch(2);
    try {
        AtomicReference<InstrumentedPool<PooledConnection>> pool = new AtomicReference<>();
        List<? extends Signal<? extends Connection>> list = Flux.range(0, 5).flatMapDelayError(i -> TcpClient.create(provider).port(server.port()).doOnConnected(conn -> {
            ConcurrentMap<PooledConnectionProvider.PoolKey, InstrumentedPool<PooledConnection>> pools = provider.channelPools;
            pool.set(pools.get(pools.keySet().toArray()[0]));
        }).doOnDisconnected(conn -> latch.countDown()).handle((in, out) -> in.receive().then()).wiretap(true).connect().materialize(), 256, 32).collectList().doFinally(fin -> latch.countDown()).block(Duration.ofSeconds(30));
        assertThat(latch.await(30, TimeUnit.SECONDS)).as("latch 30s").isTrue();
        assertThat(list).isNotNull().hasSize(5);
        int onNext = 0;
        int onError = 0;
        String msg = "Pool#acquire(Duration) has been pending for more than the configured timeout of 10ms";
        for (int i = 0; i < 5; i++) {
            Signal<? extends Connection> signal = list.get(i);
            if (signal.isOnNext()) {
                onNext++;
            } else if (signal.getThrowable() instanceof TimeoutException && msg.equals(signal.getThrowable().getMessage())) {
                onError++;
            }
        }
        assertThat(onNext).isEqualTo(1);
        assertThat(onError).isEqualTo(4);
        assertThat(pool.get().metrics().acquiredSize()).as("currently acquired").isEqualTo(0);
        assertThat(pool.get().metrics().idleSize()).as("currently idle").isEqualTo(0);
    } finally {
        server.disposeNow();
        provider.dispose();
    }
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) StepVerifier(reactor.test.StepVerifier) SocketAddress(java.net.SocketAddress) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) InstrumentedPool(reactor.pool.InstrumentedPool) TimeoutException(java.util.concurrent.TimeoutException) TcpClient(reactor.netty.tcp.TcpClient) ConnectionObserver(reactor.netty.ConnectionObserver) Future(java.util.concurrent.Future) PoolAcquirePendingLimitException(reactor.pool.PoolAcquirePendingLimitException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Map(java.util.Map) NameResolverProvider(reactor.netty.transport.NameResolverProvider) PooledRef(reactor.pool.PooledRef) AddressResolver(io.netty.resolver.AddressResolver) Awaitility.await(org.awaitility.Awaitility.await) AddressUtils(reactor.netty.transport.AddressUtils) Signal(reactor.core.publisher.Signal) InetSocketAddress(java.net.InetSocketAddress) Executors(java.util.concurrent.Executors) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) SchedulerClock(reactor.scheduler.clock.SchedulerClock) LockSupport(java.util.concurrent.locks.LockSupport) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) AddressResolverGroup(io.netty.resolver.AddressResolverGroup) DisposableServer(reactor.netty.DisposableServer) TcpClientTests(reactor.netty.tcp.TcpClientTests) ChannelOption(io.netty.channel.ChannelOption) LoggingHandler(io.netty.handler.logging.LoggingHandler) SocketUtils(reactor.netty.SocketUtils) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) ConcurrentMap(java.util.concurrent.ConcurrentMap) PooledConnection(reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) TcpResources(reactor.netty.tcp.TcpResources) ConnectException(java.net.ConnectException) Connection(reactor.netty.Connection) ClientTransportConfig(reactor.netty.transport.ClientTransportConfig) EventLoopGroup(io.netty.channel.EventLoopGroup) VirtualTimeScheduler(reactor.test.scheduler.VirtualTimeScheduler) NetUtil(io.netty.util.NetUtil) Mono(reactor.core.publisher.Mono) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) Flux(reactor.core.publisher.Flux) ChannelMetricsRecorder(reactor.netty.channel.ChannelMetricsRecorder) TcpServer(reactor.netty.tcp.TcpServer) DefaultAddressResolverGroup(io.netty.resolver.DefaultAddressResolverGroup) Collections(java.util.Collections) ConcurrentMap(java.util.concurrent.ConcurrentMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) PooledConnection(reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection) DisposableServer(reactor.netty.DisposableServer) InstrumentedPool(reactor.pool.InstrumentedPool) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.jupiter.api.Test)

Example 3 with PooledConnection

use of reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection in project reactor-netty by reactor.

the class DefaultPooledConnectionProviderTest method testIssue951_MaxPendingAcquire.

@Test
void testIssue951_MaxPendingAcquire() throws InterruptedException {
    DisposableServer server = TcpServer.create().port(0).handle((in, out) -> out.sendString(Mono.just("test").delayElement(Duration.ofMillis(100)))).wiretap(true).bindNow();
    DefaultPooledConnectionProvider provider = (DefaultPooledConnectionProvider) ConnectionProvider.builder("testIssue951_MaxPendingAcquire").maxConnections(1).pendingAcquireTimeout(Duration.ofMillis(30)).pendingAcquireMaxCount(1).build();
    CountDownLatch latch = new CountDownLatch(2);
    try {
        AtomicReference<InstrumentedPool<PooledConnection>> pool = new AtomicReference<>();
        List<? extends Signal<? extends Connection>> list = Flux.range(0, 3).flatMapDelayError(i -> TcpClient.create(provider).port(server.port()).doOnConnected(conn -> {
            ConcurrentMap<PooledConnectionProvider.PoolKey, InstrumentedPool<PooledConnection>> pools = provider.channelPools;
            pool.set(pools.get(pools.keySet().toArray()[0]));
        }).doOnDisconnected(conn -> latch.countDown()).handle((in, out) -> in.receive().then()).wiretap(true).connect().materialize(), 256, 32).collectList().doFinally(fin -> latch.countDown()).block(Duration.ofSeconds(30));
        assertThat(latch.await(30, TimeUnit.SECONDS)).as("latch 30s").isTrue();
        assertThat(list).isNotNull().hasSize(3);
        int onNext = 0;
        int onErrorTimeout = 0;
        int onErrorPendingAcquire = 0;
        String msg1 = "Pool#acquire(Duration) has been pending for more than the configured timeout of 30ms";
        String msg2 = "Pending acquire queue has reached its maximum size of 1";
        for (int i = 0; i < 3; i++) {
            Signal<? extends Connection> signal = list.get(i);
            if (signal.isOnNext()) {
                onNext++;
            } else if (signal.getThrowable() instanceof TimeoutException && msg1.equals(signal.getThrowable().getMessage())) {
                onErrorTimeout++;
            } else if (signal.getThrowable() instanceof PoolAcquirePendingLimitException && msg2.equals(signal.getThrowable().getMessage())) {
                onErrorPendingAcquire++;
            }
        }
        assertThat(onNext).isEqualTo(1);
        assertThat(onErrorTimeout).isEqualTo(1);
        assertThat(onErrorPendingAcquire).isEqualTo(1);
        assertThat(pool.get().metrics().acquiredSize()).as("currently acquired").isEqualTo(0);
        assertThat(pool.get().metrics().idleSize()).as("currently idle").isEqualTo(0);
    } finally {
        server.disposeNow();
        provider.dispose();
    }
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) StepVerifier(reactor.test.StepVerifier) SocketAddress(java.net.SocketAddress) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) InstrumentedPool(reactor.pool.InstrumentedPool) TimeoutException(java.util.concurrent.TimeoutException) TcpClient(reactor.netty.tcp.TcpClient) ConnectionObserver(reactor.netty.ConnectionObserver) Future(java.util.concurrent.Future) PoolAcquirePendingLimitException(reactor.pool.PoolAcquirePendingLimitException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Map(java.util.Map) NameResolverProvider(reactor.netty.transport.NameResolverProvider) PooledRef(reactor.pool.PooledRef) AddressResolver(io.netty.resolver.AddressResolver) Awaitility.await(org.awaitility.Awaitility.await) AddressUtils(reactor.netty.transport.AddressUtils) Signal(reactor.core.publisher.Signal) InetSocketAddress(java.net.InetSocketAddress) Executors(java.util.concurrent.Executors) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) SchedulerClock(reactor.scheduler.clock.SchedulerClock) LockSupport(java.util.concurrent.locks.LockSupport) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) AddressResolverGroup(io.netty.resolver.AddressResolverGroup) DisposableServer(reactor.netty.DisposableServer) TcpClientTests(reactor.netty.tcp.TcpClientTests) ChannelOption(io.netty.channel.ChannelOption) LoggingHandler(io.netty.handler.logging.LoggingHandler) SocketUtils(reactor.netty.SocketUtils) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) ConcurrentMap(java.util.concurrent.ConcurrentMap) PooledConnection(reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) TcpResources(reactor.netty.tcp.TcpResources) ConnectException(java.net.ConnectException) Connection(reactor.netty.Connection) ClientTransportConfig(reactor.netty.transport.ClientTransportConfig) EventLoopGroup(io.netty.channel.EventLoopGroup) VirtualTimeScheduler(reactor.test.scheduler.VirtualTimeScheduler) NetUtil(io.netty.util.NetUtil) Mono(reactor.core.publisher.Mono) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) Flux(reactor.core.publisher.Flux) ChannelMetricsRecorder(reactor.netty.channel.ChannelMetricsRecorder) TcpServer(reactor.netty.tcp.TcpServer) DefaultAddressResolverGroup(io.netty.resolver.DefaultAddressResolverGroup) Collections(java.util.Collections) ConcurrentMap(java.util.concurrent.ConcurrentMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) PooledConnection(reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection) DisposableServer(reactor.netty.DisposableServer) InstrumentedPool(reactor.pool.InstrumentedPool) PoolAcquirePendingLimitException(reactor.pool.PoolAcquirePendingLimitException) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.jupiter.api.Test)

Aggregations

EventLoopGroup (io.netty.channel.EventLoopGroup)3 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)3 ConnectException (java.net.ConnectException)3 InetSocketAddress (java.net.InetSocketAddress)3 CountDownLatch (java.util.concurrent.CountDownLatch)3 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)3 Test (org.junit.jupiter.api.Test)3 ConnectionObserver (reactor.netty.ConnectionObserver)3 ChannelOption (io.netty.channel.ChannelOption)2 LoggingHandler (io.netty.handler.logging.LoggingHandler)2 AddressResolver (io.netty.resolver.AddressResolver)2 AddressResolverGroup (io.netty.resolver.AddressResolverGroup)2 DefaultAddressResolverGroup (io.netty.resolver.DefaultAddressResolverGroup)2 NetUtil (io.netty.util.NetUtil)2 SocketAddress (java.net.SocketAddress)2 Duration (java.time.Duration)2 Arrays (java.util.Arrays)2 Collections (java.util.Collections)2 List (java.util.List)2 Map (java.util.Map)2