Search in sources :

Example 1 with PoolShutdownException

use of reactor.netty.internal.shaded.reactor.pool.PoolShutdownException in project reactor-netty by reactor.

the class Http2Pool method drainLoop.

void drainLoop() {
    recordInteractionTimestamp();
    int maxPending = poolConfig.maxPending();
    for (; ; ) {
        @SuppressWarnings("unchecked") ConcurrentLinkedQueue<Slot> resources = CONNECTIONS.get(this);
        @SuppressWarnings("unchecked") ConcurrentLinkedDeque<Borrower> borrowers = PENDING.get(this);
        if (resources == null || borrowers == TERMINATED) {
            return;
        }
        int borrowersCount = borrowers.size();
        if (borrowersCount != 0) {
            // find a connection that can be used for opening a new stream
            Slot slot = findConnection(resources);
            if (slot != null) {
                Borrower borrower = borrowers.pollFirst();
                if (borrower == null) {
                    resources.offer(slot);
                    continue;
                }
                if (isDisposed()) {
                    borrower.fail(new PoolShutdownException());
                    return;
                }
                if (slot.incrementConcurrencyAndGet() > 1) {
                    borrower.stopPendingCountdown();
                    if (log.isDebugEnabled()) {
                        log.debug(format(slot.connection.channel(), "Channel activated"));
                    }
                    ACQUIRED.incrementAndGet(this);
                    // we are ready here, the connection can be used for opening another stream
                    slot.deactivate();
                    poolConfig.acquisitionScheduler().schedule(() -> borrower.deliver(new Http2PooledRef(slot)));
                } else {
                    borrowers.offerFirst(borrower);
                    continue;
                }
            } else {
                int permits = poolConfig.allocationStrategy().getPermits(1);
                if (permits <= 0) {
                    if (maxPending >= 0) {
                        borrowersCount = borrowers.size();
                        int toCull = borrowersCount - maxPending;
                        for (int i = 0; i < toCull; i++) {
                            Borrower extraneous = borrowers.pollFirst();
                            if (extraneous != null) {
                                pendingAcquireLimitReached(extraneous, maxPending);
                            }
                        }
                    }
                } else {
                    Borrower borrower = borrowers.pollFirst();
                    if (borrower == null) {
                        continue;
                    }
                    if (isDisposed()) {
                        borrower.fail(new PoolShutdownException());
                        return;
                    }
                    borrower.stopPendingCountdown();
                    Mono<Connection> allocator = poolConfig.allocator();
                    Mono<Connection> primary = allocator.doOnEach(sig -> {
                        if (sig.isOnNext()) {
                            Connection newInstance = sig.get();
                            assert newInstance != null;
                            Slot newSlot = new Slot(this, newInstance);
                            if (log.isDebugEnabled()) {
                                log.debug(format(newInstance.channel(), "Channel activated"));
                            }
                            ACQUIRED.incrementAndGet(this);
                            newSlot.incrementConcurrencyAndGet();
                            newSlot.deactivate();
                            borrower.deliver(new Http2PooledRef(newSlot));
                        } else if (sig.isOnError()) {
                            Throwable error = sig.getThrowable();
                            assert error != null;
                            poolConfig.allocationStrategy().returnPermits(1);
                            borrower.fail(error);
                        }
                    }).contextWrite(borrower.currentContext());
                    primary.subscribe(alreadyPropagated -> {
                    }, alreadyPropagatedOrLogged -> drain(), this::drain);
                }
            }
        }
        if (WIP.decrementAndGet(this) == 0) {
            recordInteractionTimestamp();
            break;
        }
    }
}
Also used : AtomicIntegerFieldUpdater(java.util.concurrent.atomic.AtomicIntegerFieldUpdater) Disposable(reactor.core.Disposable) Scannable(reactor.core.Scannable) PoolShutdownException(reactor.netty.internal.shaded.reactor.pool.PoolShutdownException) PooledRef(reactor.netty.internal.shaded.reactor.pool.PooledRef) ReactorNetty.format(reactor.netty.ReactorNetty.format) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Nullable(reactor.util.annotation.Nullable) ConnectionObserver(reactor.netty.ConnectionObserver) CoreSubscriber(reactor.core.CoreSubscriber) Loggers(reactor.util.Loggers) PooledRefMetadata(reactor.netty.internal.shaded.reactor.pool.PooledRefMetadata) Duration(java.time.Duration) Logger(reactor.util.Logger) Schedulers(reactor.core.scheduler.Schedulers) Disposables(reactor.core.Disposables) Connection(reactor.netty.Connection) Operators(reactor.core.publisher.Operators) AtomicReferenceFieldUpdater(java.util.concurrent.atomic.AtomicReferenceFieldUpdater) ChannelOperations(reactor.netty.channel.ChannelOperations) InstrumentedPool(reactor.netty.internal.shaded.reactor.pool.InstrumentedPool) Context(reactor.util.context.Context) Http2FrameCodec(io.netty.handler.codec.http2.Http2FrameCodec) Mono(reactor.core.publisher.Mono) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) Subscription(org.reactivestreams.Subscription) PoolConfig(reactor.netty.internal.shaded.reactor.pool.PoolConfig) PoolAcquireTimeoutException(reactor.netty.internal.shaded.reactor.pool.PoolAcquireTimeoutException) Clock(java.time.Clock) Http2MultiplexHandler(io.netty.handler.codec.http2.Http2MultiplexHandler) PoolAcquirePendingLimitException(reactor.netty.internal.shaded.reactor.pool.PoolAcquirePendingLimitException) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) PoolShutdownException(reactor.netty.internal.shaded.reactor.pool.PoolShutdownException) Connection(reactor.netty.Connection)

Example 2 with PoolShutdownException

use of reactor.netty.internal.shaded.reactor.pool.PoolShutdownException in project reactor-netty by reactor.

the class DefaultPooledConnectionProviderTest method testPoolGracefulShutdown.

@ParameterizedTest(name = "{displayName}({argumentsWithNames})")
@ValueSource(booleans = { false, true })
void testPoolGracefulShutdown(boolean enableGracefulShutdown) {
    disposableServer = createServer().handle((req, res) -> res.sendString(Mono.just("testPoolGracefulShutdown").delayElement(Duration.ofMillis(50)))).bindNow();
    ConnectionProvider.Builder providerBuilder = ConnectionProvider.builder("testPoolGracefulShutdown").maxConnections(1);
    if (enableGracefulShutdown) {
        providerBuilder.disposeTimeout(Duration.ofMillis(200));
    }
    ConnectionProvider provider = providerBuilder.build();
    HttpClient client = createClient(provider, disposableServer.port()).doOnDisconnected(conn -> {
        if (!provider.isDisposed()) {
            provider.dispose();
        }
    });
    List<Signal<String>> result = Flux.range(0, 2).flatMap(i -> client.get().uri("/").responseContent().aggregate().asString()).materialize().collectList().block(Duration.ofSeconds(5));
    assertThat(result).isNotNull();
    int onNext = 0;
    int onError = 0;
    for (Signal<String> signal : result) {
        if (signal.isOnNext()) {
            onNext++;
            assertThat(signal.get()).isEqualTo("testPoolGracefulShutdown");
        } else if (signal.getThrowable() instanceof PoolShutdownException) {
            onError++;
        }
    }
    if (enableGracefulShutdown) {
        assertThat(onNext).isEqualTo(2);
        assertThat(onError).isEqualTo(0);
    } else {
        assertThat(onNext).isEqualTo(1);
        assertThat(onError).isEqualTo(1);
    }
}
Also used : StepVerifier(reactor.test.StepVerifier) Http11SslContextSpec(reactor.netty.http.Http11SslContextSpec) SocketAddress(java.net.SocketAddress) PoolShutdownException(reactor.netty.internal.shaded.reactor.pool.PoolShutdownException) HttpProtocol(reactor.netty.http.HttpProtocol) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Http2SslContextSpec(reactor.netty.http.Http2SslContextSpec) BaseHttpTest(reactor.netty.BaseHttpTest) Disabled(org.junit.jupiter.api.Disabled) StringUtils(org.apache.commons.lang3.StringUtils) Nullable(reactor.util.annotation.Nullable) AtomicReference(java.util.concurrent.atomic.AtomicReference) ConcurrentMap(java.util.concurrent.ConcurrentMap) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) InsecureTrustManagerFactory(io.netty.handler.ssl.util.InsecureTrustManagerFactory) ConnectionObserver(reactor.netty.ConnectionObserver) ChannelPromise(io.netty.channel.ChannelPromise) BeforeAll(org.junit.jupiter.api.BeforeAll) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) ByteBufMono(reactor.netty.ByteBufMono) DefaultChannelPromise(io.netty.channel.DefaultChannelPromise) MethodSource(org.junit.jupiter.params.provider.MethodSource) ValueSource(org.junit.jupiter.params.provider.ValueSource) ChannelOutboundHandlerAdapter(io.netty.channel.ChannelOutboundHandlerAdapter) SslContext(io.netty.handler.ssl.SslContext) SelfSignedCertificate(io.netty.handler.ssl.util.SelfSignedCertificate) InstrumentedPool(reactor.netty.internal.shaded.reactor.pool.InstrumentedPool) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) Mono(reactor.core.publisher.Mono) IOException(java.io.IOException) Signal(reactor.core.publisher.Signal) CertificateException(java.security.cert.CertificateException) InetSocketAddress(java.net.InetSocketAddress) Channel(io.netty.channel.Channel) Test(org.junit.jupiter.api.Test) TimeUnit(java.util.concurrent.TimeUnit) Flux(reactor.core.publisher.Flux) CountDownLatch(java.util.concurrent.CountDownLatch) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) HttpServer(reactor.netty.http.server.HttpServer) SSLException(javax.net.ssl.SSLException) List(java.util.List) SslProvider(io.netty.handler.ssl.SslProvider) SslContextBuilder(io.netty.handler.ssl.SslContextBuilder) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) HttpClient(reactor.netty.http.client.HttpClient) Signal(reactor.core.publisher.Signal) HttpClient(reactor.netty.http.client.HttpClient) PoolShutdownException(reactor.netty.internal.shaded.reactor.pool.PoolShutdownException) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 3 with PoolShutdownException

use of reactor.netty.internal.shaded.reactor.pool.PoolShutdownException in project reactor-netty by reactor.

the class Http2Pool method doAcquire.

void doAcquire(Borrower borrower) {
    if (isDisposed()) {
        borrower.fail(new PoolShutdownException());
        return;
    }
    pendingOffer(borrower);
    drain();
}
Also used : PoolShutdownException(reactor.netty.internal.shaded.reactor.pool.PoolShutdownException)

Example 4 with PoolShutdownException

use of reactor.netty.internal.shaded.reactor.pool.PoolShutdownException in project reactor-netty by reactor.

the class Http2Pool method disposeLater.

@Override
public Mono<Void> disposeLater() {
    return Mono.defer(() -> {
        recordInteractionTimestamp();
        @SuppressWarnings("unchecked") ConcurrentLinkedDeque<Borrower> q = PENDING.getAndSet(this, TERMINATED);
        if (q != TERMINATED) {
            Borrower p;
            while ((p = q.pollFirst()) != null) {
                p.fail(new PoolShutdownException());
            }
            // the last stream on that connection will release the connection to the parent pool
            // the structure should not contain connections with 0 streams as the last stream on that connection
            // always removes the connection from this pool
            CONNECTIONS.getAndSet(this, null);
        }
        return Mono.empty();
    });
}
Also used : PoolShutdownException(reactor.netty.internal.shaded.reactor.pool.PoolShutdownException)

Aggregations

PoolShutdownException (reactor.netty.internal.shaded.reactor.pool.PoolShutdownException)4 Duration (java.time.Duration)2 TimeUnit (java.util.concurrent.TimeUnit)2 Mono (reactor.core.publisher.Mono)2 ConnectionObserver (reactor.netty.ConnectionObserver)2 InstrumentedPool (reactor.netty.internal.shaded.reactor.pool.InstrumentedPool)2 Nullable (reactor.util.annotation.Nullable)2 Channel (io.netty.channel.Channel)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 ChannelOutboundHandlerAdapter (io.netty.channel.ChannelOutboundHandlerAdapter)1 ChannelPromise (io.netty.channel.ChannelPromise)1 DefaultChannelPromise (io.netty.channel.DefaultChannelPromise)1 HttpHeaderNames (io.netty.handler.codec.http.HttpHeaderNames)1 HttpResponseStatus (io.netty.handler.codec.http.HttpResponseStatus)1 Http2FrameCodec (io.netty.handler.codec.http2.Http2FrameCodec)1 Http2MultiplexHandler (io.netty.handler.codec.http2.Http2MultiplexHandler)1 SslContext (io.netty.handler.ssl.SslContext)1 SslContextBuilder (io.netty.handler.ssl.SslContextBuilder)1 SslProvider (io.netty.handler.ssl.SslProvider)1 InsecureTrustManagerFactory (io.netty.handler.ssl.util.InsecureTrustManagerFactory)1