Search in sources :

Example 1 with InstrumentedPool

use of reactor.pool.InstrumentedPool 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 2 with InstrumentedPool

use of reactor.pool.InstrumentedPool in project reactor-netty by reactor.

the class PooledConnectionProvider method acquire.

@Override
public final Mono<? extends Connection> acquire(TransportConfig config, ConnectionObserver connectionObserver, @Nullable Supplier<? extends SocketAddress> remote, @Nullable AddressResolverGroup<?> resolverGroup) {
    Objects.requireNonNull(config, "config");
    Objects.requireNonNull(connectionObserver, "connectionObserver");
    Objects.requireNonNull(remote, "remoteAddress");
    Objects.requireNonNull(resolverGroup, "resolverGroup");
    return Mono.create(sink -> {
        SocketAddress remoteAddress = Objects.requireNonNull(remote.get(), "Remote Address supplier returned null");
        PoolKey holder = new PoolKey(remoteAddress, config.channelHash());
        PoolFactory<T> poolFactory = poolFactory(remoteAddress);
        InstrumentedPool<T> pool = MapUtils.computeIfAbsent(channelPools, holder, poolKey -> {
            if (log.isDebugEnabled()) {
                log.debug("Creating a new [{}] client pool [{}] for [{}]", name, poolFactory, remoteAddress);
            }
            InstrumentedPool<T> newPool = createPool(config, poolFactory, remoteAddress, resolverGroup);
            if (poolFactory.metricsEnabled || config.metricsRecorder() != null) {
                // registrar is null when metrics are enabled on HttpClient level or
                // with the `metrics(boolean metricsEnabled)` method on ConnectionProvider
                String id = poolKey.hashCode() + "";
                if (poolFactory.registrar != null) {
                    poolFactory.registrar.get().registerMetrics(name, id, remoteAddress, new DelegatingConnectionPoolMetrics(newPool.metrics()));
                } else if (Metrics.isInstrumentationAvailable()) {
                    // work directly with the pool otherwise a weak reference is needed to ConnectionPoolMetrics
                    // we don't want to keep another map with weak references
                    registerDefaultMetrics(id, remoteAddress, newPool.metrics());
                }
            }
            return newPool;
        });
        EventLoop eventLoop = config.loopResources().onClient(config.isPreferNative()).next();
        pool.acquire(Duration.ofMillis(poolFactory.pendingAcquireTimeout)).contextWrite(ctx -> ctx.put(CONTEXT_CALLER_EVENTLOOP, eventLoop)).subscribe(createDisposableAcquire(config, connectionObserver, poolFactory.pendingAcquireTimeout, pool, sink));
    });
}
Also used : ReactorNetty(reactor.netty.ReactorNetty) SamplingAllocationStrategy(reactor.pool.introspection.SamplingAllocationStrategy) Disposable(reactor.core.Disposable) SocketAddress(java.net.SocketAddress) ReactorNetty.format(reactor.netty.ReactorNetty.format) InstrumentedPool(reactor.pool.InstrumentedPool) MonoSink(reactor.core.publisher.MonoSink) HashMap(java.util.HashMap) Nullable(reactor.util.annotation.Nullable) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ConcurrentMap(java.util.concurrent.ConcurrentMap) InetAddress(java.net.InetAddress) ConnectionObserver(reactor.netty.ConnectionObserver) BiPredicate(java.util.function.BiPredicate) CoreSubscriber(reactor.core.CoreSubscriber) TransportConfig(reactor.netty.transport.TransportConfig) AllocationStrategy(reactor.pool.AllocationStrategy) Loggers(reactor.util.Loggers) Metrics(reactor.netty.internal.util.Metrics) Logger(reactor.util.Logger) Duration(java.time.Duration) Map(java.util.Map) Schedulers(reactor.core.scheduler.Schedulers) MapUtils(reactor.netty.internal.util.MapUtils) PoolConfig(reactor.pool.PoolConfig) PENDING_ACQUIRE_MAX_COUNT_NOT_SPECIFIED(reactor.netty.resources.ConnectionProvider.ConnectionPoolSpec.PENDING_ACQUIRE_MAX_COUNT_NOT_SPECIFIED) Connection(reactor.netty.Connection) PooledRef(reactor.pool.PooledRef) Publisher(org.reactivestreams.Publisher) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) PoolBuilder(reactor.pool.PoolBuilder) Mono(reactor.core.publisher.Mono) Pool(reactor.pool.Pool) GracefulShutdownInstrumentedPool(reactor.pool.decorators.GracefulShutdownInstrumentedPool) EventLoop(io.netty.channel.EventLoop) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) Channel(io.netty.channel.Channel) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) AddressResolverGroup(io.netty.resolver.AddressResolverGroup) List(java.util.List) Clock(java.time.Clock) PooledRefMetadata(reactor.pool.PooledRefMetadata) InstrumentedPoolDecorators(reactor.pool.decorators.InstrumentedPoolDecorators) EventLoop(io.netty.channel.EventLoop) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress)

Example 3 with InstrumentedPool

use of reactor.pool.InstrumentedPool 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)

Example 4 with InstrumentedPool

use of reactor.pool.InstrumentedPool in project reactor-netty by reactor.

the class DefaultPooledConnectionProviderTest method doTestIssue1790.

private void doTestIssue1790(boolean fifoPool) {
    DefaultPooledConnectionProvider provider;
    if (fifoPool) {
        provider = (DefaultPooledConnectionProvider) ConnectionProvider.builder("testIssue1790").maxConnections(1).fifo().build();
    } else {
        provider = (DefaultPooledConnectionProvider) ConnectionProvider.builder("testIssue1790").maxConnections(1).lifo().build();
    }
    DisposableServer disposableServer = TcpServer.create().port(0).wiretap(true).bindNow();
    Connection connection = null;
    try {
        connection = TcpClient.create(provider).port(disposableServer.port()).wiretap(true).connectNow();
        assertThat(provider.channelPools).hasSize(1);
        @SuppressWarnings({ "unchecked", "rawtypes" }) InstrumentedPool<DefaultPooledConnectionProvider.PooledConnection> channelPool = provider.channelPools.values().toArray(new InstrumentedPool[0])[0];
        assertThat(channelPool.metrics()).withFailMessage("Reactor-netty relies on Reactor-pool instrumented pool.metrics()" + " to be the pool instance itself, got <%s> and <%s>", channelPool.metrics(), channelPool).isSameAs(channelPool);
    } finally {
        if (connection != null) {
            connection.disposeNow();
        }
        disposableServer.disposeNow();
        provider.disposeLater().block(Duration.ofSeconds(5));
    }
}
Also used : PooledConnection(reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection) DisposableServer(reactor.netty.DisposableServer) PooledConnection(reactor.netty.resources.DefaultPooledConnectionProvider.PooledConnection) Connection(reactor.netty.Connection) InstrumentedPool(reactor.pool.InstrumentedPool)

Aggregations

Connection (reactor.netty.Connection)4 AddressResolverGroup (io.netty.resolver.AddressResolverGroup)3 InetSocketAddress (java.net.InetSocketAddress)3 SocketAddress (java.net.SocketAddress)3 Duration (java.time.Duration)3 List (java.util.List)3 Map (java.util.Map)3 ConcurrentMap (java.util.concurrent.ConcurrentMap)3 TimeUnit (java.util.concurrent.TimeUnit)3 Supplier (java.util.function.Supplier)3 Mono (reactor.core.publisher.Mono)3 ConnectionObserver (reactor.netty.ConnectionObserver)3 DisposableServer (reactor.netty.DisposableServer)3 InstrumentedPool (reactor.pool.InstrumentedPool)3 ChannelOption (io.netty.channel.ChannelOption)2 EventLoopGroup (io.netty.channel.EventLoopGroup)2 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)2 LoggingHandler (io.netty.handler.logging.LoggingHandler)2 AddressResolver (io.netty.resolver.AddressResolver)2 DefaultAddressResolverGroup (io.netty.resolver.DefaultAddressResolverGroup)2