@Override
    public boolean release(final PooledConnection conn) {

        conn.stopRequestTimer();
        releaseConnCounter.increment();
        connsInUse.decrementAndGet();

        final DiscoveryResult discoveryResult = conn.getServer();
        updateServerStatsOnRelease(conn);

        boolean released = false;


        if (conn.isShouldClose()) {
            // Close and discard the connection, as it has been flagged (possibly due to receiving a non-channel error
            // like a 503).
            conn.setInPool(false);
            conn.close();
                LOG.debug(
                        "[{}] closing conn flagged to be closed",
                        conn.getChannel().id());
        } else if(isConnectionExpired(conn.getUsageCount())) {
            conn.setInPool(false);
            conn.close();
            closeExpiredConnLifetimeCounter.increment();
            LOG.debug(
                    "[{}] closing conn lifetime expired, usage: {}",
                    conn.getChannel().id(),
                    conn.getUsageCount());
        } else if (connPoolConfig.isCloseOnCircuitBreakerEnabled() && discoveryResult.isCircuitBreakerTripped()) {
            LOG.debug(
                    "[{}] closing conn, server circuit breaker tripped",
                    conn.getChannel().id());
            circuitBreakerClose.increment();
            // Don't put conns for currently circuit-tripped servers back into the pool.
            conn.setInPool(false);
            conn.close();
        } else if (!conn.isActive()) {
            LOG.debug("[{}] conn inactive, cleaning up", conn.getChannel().id());
            // Connection is already closed, so discard.
            alreadyClosedCounter.increment();
            // make sure to decrement OpenConnectionCounts
            conn.updateServerStats();
            conn.setInPool(false);
        } else {
            releaseHandlers(conn);

            // Attempt to return connection to the pool.
            IConnectionPool pool = perServerPools.get(discoveryResult);
            if (pool != null) {
                released = pool.release(conn);
            } else {
                // The pool for this server no longer exists (maybe due to it falling out of
                // discovery).
                conn.setInPool(false);
                released = false;
                conn.close();
            }

            LOG.debug("PooledConnection released: {}", conn);
        }

        return released;
    }
@Test
    void closeOnCircuitBreaker() {
        final OriginName originName = OriginName.fromVipAndApp("whatever", "whatever");
        DefaultClientChannelManager manager =
                new DefaultClientChannelManager(
                        originName,
                        new DefaultClientConfigImpl(),
                        Mockito.mock(DynamicServerResolver.class),
                        new NoopRegistry()) {
                    @Override
                    protected void updateServerStatsOnRelease(PooledConnection conn) {}
                };

        PooledConnection connection = mock(PooledConnection.class);
        DiscoveryResult discoveryResult = mock(DiscoveryResult.class);
        doReturn(discoveryResult).when(connection).getServer();
        doReturn(true).when(discoveryResult).isCircuitBreakerTripped();
        doReturn(new EmbeddedChannel()).when(connection).getChannel();

        Truth.assertThat(manager.release(connection)).isFalse();
        verify(connection).setInPool(false);
        verify(connection).close();
    }