diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnection.java b/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnection.java index 8035010730..9860a9eb3b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnection.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnection.java @@ -70,7 +70,7 @@ public NettyConnection( Channel channel, ChannelPool channelPool, Clock clock, M this.clock = clock; this.metricsListener = metricsListener; this.inUseEvent = metricsListener.createListenerEvent(); - metricsListener.afterAcquiredOrCreated( this.serverAddress, this.inUseEvent ); + metricsListener.afterConnectionCreated( this.serverAddress, this.inUseEvent ); } @Override @@ -131,11 +131,11 @@ public CompletionStage release() { if ( status.compareAndSet( Status.OPEN, Status.RELEASED ) ) { - metricsListener.afterReleased( this.serverAddress, this.inUseEvent ); ChannelReleasingResetResponseHandler handler = new ChannelReleasingResetResponseHandler( channel, channelPool, messageDispatcher, clock, releaseFuture ); writeResetMessageIfNeeded( handler, false ); + metricsListener.afterConnectionReleased( this.serverAddress, this.inUseEvent ); } return releaseFuture; } @@ -145,11 +145,11 @@ public void terminateAndRelease( String reason ) { if ( status.compareAndSet( Status.OPEN, Status.TERMINATED ) ) { - metricsListener.afterReleased( this.serverAddress, this.inUseEvent ); setTerminationReason( channel, reason ); channel.close(); channelPool.release( channel ); releaseFuture.complete( null ); + metricsListener.afterConnectionReleased( this.serverAddress, this.inUseEvent ); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java index 474ec9e56e..7dea354201 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java @@ -95,13 +95,16 @@ public CompletionStage acquire( BoltServerAddress address ) { try { - processAcquisitionError( error ); + processAcquisitionError( address, error ); assertNotClosed( address, channel, pool ); - return new NettyConnection( channel, pool, clock, metricsListener ); + NettyConnection nettyConnection = new NettyConnection( channel, pool, clock, metricsListener ); + + metricsListener.afterAcquiredOrCreated( address, acquireEvent ); + return nettyConnection; } finally { - metricsListener.afterAcquiringOrCreating( address, acquireEvent ); + metricsListener.afterAcquiringOrCreating( address ); } } ); } @@ -171,9 +174,9 @@ public CompletionStage close() } @Override - public boolean isOpen() + public boolean isOpen( BoltServerAddress address ) { - return !closed.get(); + return pools.containsKey( address ); } private ChannelPool getOrCreatePool( BoltServerAddress address ) @@ -210,7 +213,7 @@ private EventLoopGroup eventLoopGroup() return bootstrap.config().group(); } - private void processAcquisitionError( Throwable error ) + private void processAcquisitionError( BoltServerAddress serverAddress, Throwable error ) { Throwable cause = Futures.completionExceptionCause( error ); if ( cause != null ) @@ -219,6 +222,7 @@ private void processAcquisitionError( Throwable error ) { // NettyChannelPool returns future failed with TimeoutException if acquire operation takes more than // configured time, translate this exception to a prettier one and re-throw + metricsListener.afterTimedOutToAcquireOrCreate( serverAddress ); throw new ClientException( "Unable to acquire connection from the pool within configured maximum time of " + settings.connectionAcquisitionTimeout() + "ms" ); diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelPool.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelPool.java index e350ae0388..c7475d6f46 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelPool.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelPool.java @@ -60,7 +60,7 @@ public NettyChannelPool( BoltServerAddress address, ChannelConnector connector, @Override protected ChannelFuture connectChannel( Bootstrap bootstrap ) { - ListenerEvent creatingEvent = handler.beforeChannelCreating( address ); + ListenerEvent creatingEvent = handler.channelCreating( address ); ChannelFuture channelFuture = connector.connect( address, bootstrap ); channelFuture.addListener( future -> { @@ -68,14 +68,13 @@ protected ChannelFuture connectChannel( Bootstrap bootstrap ) { // notify pool handler about a successful connection Channel channel = channelFuture.channel(); - handler.channelCreated( channel ); + handler.channelCreated( channel, creatingEvent ); channel.closeFuture().addListener( closeFuture -> handler.channelClosed( channel ) ); } else { handler.channelFailedToCreate( address ); } - handler.afterChannelCreating( address, creatingEvent ); } ); return channelFuture; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java index 11e98cbad0..c4ffaef821 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java @@ -65,26 +65,26 @@ public void channelAcquired( Channel channel ) @Override public void channelCreated( Channel channel ) { - log.debug( "Channel %s created", channel ); - incrementInUse( channel ); - metricsListener.afterCreated( serverAddress( channel ) ); + throw new IllegalStateException( "Untraceable channel created." ); } - public void channelFailedToCreate( BoltServerAddress address ) + public void channelCreated( Channel channel, ListenerEvent creatingEvent ) { - metricsListener.afterFailedToCreate( address ); + log.debug( "Channel %s created", channel ); + incrementInUse( channel ); + metricsListener.afterCreated( serverAddress( channel ), creatingEvent ); } - public ListenerEvent beforeChannelCreating( BoltServerAddress address ) + public ListenerEvent channelCreating( BoltServerAddress address ) { ListenerEvent creatingEvent = metricsListener.createListenerEvent(); metricsListener.beforeCreating( address, creatingEvent ); return creatingEvent; } - public void afterChannelCreating( BoltServerAddress address, ListenerEvent creatingEvent ) + public void channelFailedToCreate( BoltServerAddress address ) { - metricsListener.afterCreating( address, creatingEvent ); + metricsListener.afterFailedToCreate( address ); } public void channelClosed( Channel channel ) diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionMetricsListener.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionMetricsListener.java index a8b55a2787..074b27faa3 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionMetricsListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionMetricsListener.java @@ -23,7 +23,7 @@ public interface ConnectionMetricsListener { void beforeCreating( ListenerEvent listenerEvent ); - void afterCreating( ListenerEvent listenerEvent ); + void afterCreated( ListenerEvent listenerEvent ); void acquiredOrCreated( ListenerEvent listenerEvent ); diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionPoolMetricsListener.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionPoolMetricsListener.java index 93f414c7f9..91cac466ce 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionPoolMetricsListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionPoolMetricsListener.java @@ -30,6 +30,10 @@ public interface ConnectionPoolMetricsListener void beforeAcquiringOrCreating( ListenerEvent listenerEvent ); - void afterAcquiringOrCreating( ListenerEvent listenerEvent ); + void afterAcquiringOrCreating(); + + void afterAcquiredOrCreated( ListenerEvent listenerEvent ); + + void afterTimedOutToAcquireOrCreate(); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalAbstractMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalAbstractMetrics.java index 959bfe8361..8a74df91de 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalAbstractMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalAbstractMetrics.java @@ -35,46 +35,61 @@ public abstract class InternalAbstractMetrics implements Metrics, MetricsListene @Override public void beforeCreating( BoltServerAddress serverAddress, ListenerEvent creatingEvent ) { + } @Override - public void afterCreating( BoltServerAddress serverAddress, ListenerEvent creatingEvent ) + public void afterCreated( BoltServerAddress serverAddress, ListenerEvent creatingEvent ) { + } @Override - public void afterCreated( BoltServerAddress serverAddress ) + public void afterFailedToCreate( BoltServerAddress serverAddress ) { + } @Override - public void afterFailedToCreate( BoltServerAddress serverAddress ) + public void afterClosed( BoltServerAddress serverAddress ) { + } @Override - public void afterClosed( BoltServerAddress serverAddress ) + public void afterTimedOutToAcquireOrCreate( BoltServerAddress serverAddress ) { + } @Override public void beforeAcquiringOrCreating( BoltServerAddress serverAddress, ListenerEvent acquireEvent ) { + } @Override - public void afterAcquiringOrCreating( BoltServerAddress serverAddress, ListenerEvent acquireEvent ) + public void afterAcquiringOrCreating( BoltServerAddress serverAddress ) { + } @Override - public void afterAcquiredOrCreated( BoltServerAddress serverAddress, ListenerEvent inUseEvent ) + public void afterAcquiredOrCreated( BoltServerAddress serverAddress, ListenerEvent acquireEvent ) { + } @Override - public void afterReleased( BoltServerAddress serverAddress, ListenerEvent inUseEvent ) + public void afterConnectionCreated( BoltServerAddress serverAddress, ListenerEvent inUseEvent ) { + + } + + @Override + public void afterConnectionReleased( BoltServerAddress serverAddress, ListenerEvent inUseEvent ) + { + } @Override @@ -83,7 +98,6 @@ public ListenerEvent createListenerEvent() return null; } - @Override public void addMetrics( BoltServerAddress address, ConnectionPoolImpl connectionPool ) { diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionMetrics.java index 6db36f3b71..20c9ce66e6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionMetrics.java @@ -66,7 +66,7 @@ public void beforeCreating( ListenerEvent connEvent ) } @Override - public void afterCreating( ListenerEvent connEvent ) + public void afterCreated( ListenerEvent connEvent ) { // finished conn creation long elapsed = connEvent.elapsed(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java index 47130fef65..207ef8f41b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java @@ -38,10 +38,15 @@ public class InternalConnectionPoolMetrics implements ConnectionPoolMetrics, Con private final BoltServerAddress address; private final ConnectionPool pool; - private AtomicLong created = new AtomicLong(); - private AtomicLong closed = new AtomicLong(); - private AtomicInteger creating = new AtomicInteger(); - private AtomicLong failedToCreate = new AtomicLong(); + private final AtomicLong closed = new AtomicLong(); + + private final AtomicInteger creating = new AtomicInteger(); + private final AtomicLong created = new AtomicLong(); + private final AtomicLong failedToCreate = new AtomicLong(); + + private final AtomicInteger acquiring = new AtomicInteger(); + private final AtomicLong acquired = new AtomicLong(); + private final AtomicLong timedOutToAcquire = new AtomicLong(); private InternalHistogram acquisitionTimeHistogram; @@ -85,13 +90,28 @@ public void afterClosed() public void beforeAcquiringOrCreating( ListenerEvent listenerEvent ) { listenerEvent.start(); + acquiring.incrementAndGet(); + } + + @Override + public void afterAcquiringOrCreating() + { + acquiring.decrementAndGet(); } @Override - public void afterAcquiringOrCreating( ListenerEvent listenerEvent ) + public void afterAcquiredOrCreated( ListenerEvent listenerEvent ) { long elapsed = listenerEvent.elapsed(); acquisitionTimeHistogram.recordValue( elapsed ); + + this.acquired.incrementAndGet(); + } + + @Override + public void afterTimedOutToAcquireOrCreate() + { + this.timedOutToAcquire.incrementAndGet(); } @Override @@ -103,13 +123,13 @@ public String uniqueName() @Override public PoolStatus poolStatus() { - if ( pool.isOpen() ) + if ( pool.isOpen( address ) ) { - return PoolStatus.Open; + return PoolStatus.OPEN; } else { - return PoolStatus.Closed; + return PoolStatus.CLOSED; } } @@ -143,12 +163,30 @@ public long failedToCreate() return failedToCreate.get(); } + @Override + public long timedOutToAcquire() + { + return timedOutToAcquire.get(); + } + @Override public long closed() { return closed.get(); } + @Override + public int acquiring() + { + return acquiring.get(); + } + + @Override + public long acquired() + { + return this.acquired.get(); + } + @Override public Histogram acquisitionTimeHistogram() { @@ -158,7 +196,9 @@ public Histogram acquisitionTimeHistogram() @Override public String toString() { - return format( "[created=%s, closed=%s, creating=%s, failedToCreate=%s inUse=%s, idle=%s, poolStatus=%s, acquisitionTimeHistogram=%s]", created(), - closed(), creating(), failedToCreate(), inUse(), idle(), poolStatus(), acquisitionTimeHistogram() ); + return format( "[created=%s, closed=%s, creating=%s, failedToCreate=%s, acquiring=%s, acquired=%s, " + + "timedOutToAcquire=%s, inUse=%s, idle=%s, poolStatus=%s, acquisitionTimeHistogram=%s]", + created(), closed(), creating(), failedToCreate(), acquiring(), acquired(), + timedOutToAcquire(), inUse(), idle(), poolStatus(), acquisitionTimeHistogram() ); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetrics.java index 23b83587b7..46c67b4914 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalMetrics.java @@ -31,6 +31,7 @@ import org.neo4j.driver.v1.exceptions.ClientException; import static java.lang.String.format; +import static java.util.Collections.unmodifiableMap; public class InternalMetrics extends InternalAbstractMetrics { @@ -61,15 +62,10 @@ public void beforeCreating( BoltServerAddress serverAddress, ListenerEvent creat } @Override - public void afterCreating( BoltServerAddress serverAddress, ListenerEvent creatingEvent ) - { - connectionMetrics( serverAddress ).afterCreating( creatingEvent ); - } - - @Override - public void afterCreated( BoltServerAddress serverAddress ) + public void afterCreated( BoltServerAddress serverAddress, ListenerEvent creatingEvent ) { poolMetrics( serverAddress ).afterCreated(); + connectionMetrics( serverAddress ).afterCreated( creatingEvent ); } @Override @@ -91,23 +87,35 @@ public void beforeAcquiringOrCreating( BoltServerAddress serverAddress, Listener } @Override - public void afterAcquiringOrCreating( BoltServerAddress serverAddress, ListenerEvent listenerEvent ) + public void afterAcquiringOrCreating( BoltServerAddress serverAddress ) + { + poolMetrics( serverAddress ).afterAcquiringOrCreating(); + } + + @Override + public void afterAcquiredOrCreated( BoltServerAddress serverAddress, ListenerEvent listenerEvent ) { - poolMetrics( serverAddress ).afterAcquiringOrCreating( listenerEvent ); + poolMetrics( serverAddress ).afterAcquiredOrCreated( listenerEvent ); } @Override - public void afterAcquiredOrCreated( BoltServerAddress serverAddress, ListenerEvent inUseEvent ) + public void afterConnectionCreated( BoltServerAddress serverAddress, ListenerEvent inUseEvent ) { connectionMetrics( serverAddress ).acquiredOrCreated( inUseEvent ); } @Override - public void afterReleased( BoltServerAddress serverAddress, ListenerEvent inUseEvent ) + public void afterConnectionReleased( BoltServerAddress serverAddress, ListenerEvent inUseEvent ) { connectionMetrics( serverAddress ).released( inUseEvent ); } + @Override + public void afterTimedOutToAcquireOrCreate( BoltServerAddress serverAddress ) + { + poolMetrics( serverAddress ).afterTimedOutToAcquireOrCreate(); + } + @Override public ListenerEvent createListenerEvent() { @@ -117,13 +125,13 @@ public ListenerEvent createListenerEvent() @Override public Map connectionPoolMetrics() { - return this.connectionPoolMetrics; + return unmodifiableMap( this.connectionPoolMetrics ); } @Override public Map connectionMetrics() { - return this.connectionMetrics; + return unmodifiableMap( this.connectionMetrics ); } @Override diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/ListenerEvent.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/ListenerEvent.java index 6eece7d235..f2deeef50b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/ListenerEvent.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/ListenerEvent.java @@ -18,7 +18,6 @@ */ package org.neo4j.driver.internal.metrics; - public interface ListenerEvent { void start(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsListener.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsListener.java index 41d337b1ac..a7473bfaae 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsListener.java @@ -18,9 +18,12 @@ */ package org.neo4j.driver.internal.metrics; +import java.util.concurrent.TimeUnit; + import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.NettyConnection; import org.neo4j.driver.internal.async.pool.ConnectionPoolImpl; +import org.neo4j.driver.v1.Config; public interface MetricsListener { @@ -31,23 +34,14 @@ public interface MetricsListener */ void beforeCreating( BoltServerAddress serverAddress, ListenerEvent creatingEvent ); - /** - * After creating a netty channel regardless succeeded or failed. - * @param serverAddress the server the netty channel binds to. - * @param creatingEvent a connection listener event registered when a connection is creating. - */ - void afterCreating( BoltServerAddress serverAddress, ListenerEvent creatingEvent ); - /** * After a netty channel is created successfully - * This method will not invoke {@link this#afterCreating(BoltServerAddress, ListenerEvent)} * @param serverAddress the server the netty channel binds to */ - void afterCreated( BoltServerAddress serverAddress ); + void afterCreated( BoltServerAddress serverAddress, ListenerEvent creatingEvent ); /** * After a netty channel is created with failure - * This method will not invoke {@link this#afterCreating(BoltServerAddress, ListenerEvent)} * @param serverAddress the server the netty channel binds to */ void afterFailedToCreate( BoltServerAddress serverAddress ); @@ -58,6 +52,13 @@ public interface MetricsListener */ void afterClosed( BoltServerAddress serverAddress ); + /** + * After failed to acquire a connection from pool within maximum connection acquisition timeout set by + * {@link Config.ConfigBuilder#withConnectionAcquisitionTimeout(long, TimeUnit)} + * @param serverAddress + */ + void afterTimedOutToAcquireOrCreate( BoltServerAddress serverAddress ); + /** * Before acquiring or creating a new netty channel from pool * @param serverAddress the server the netty channel binds to @@ -66,26 +67,31 @@ public interface MetricsListener void beforeAcquiringOrCreating( BoltServerAddress serverAddress, ListenerEvent acquireEvent ); /** - * After acquiring or creating a new netty channel from pool regardless succeeded or failed + * After acquiring or creating a new netty channel from pool regardless successfully or not. + * @param serverAddress the server the netty channel binds to + */ + void afterAcquiringOrCreating( BoltServerAddress serverAddress ); + + /** + * After acquiring or creating a new netty channel from pool successfully. * @param serverAddress the server the netty channel binds to * @param acquireEvent a pool listener event registered in pool for this acquire event */ - void afterAcquiringOrCreating( BoltServerAddress serverAddress, ListenerEvent acquireEvent ); + void afterAcquiredOrCreated( BoltServerAddress serverAddress, ListenerEvent acquireEvent ); /** * After acquiring or creating a new netty channel from pool successfully. - * This method will not invoke {@link this#afterAcquiringOrCreating(BoltServerAddress, ListenerEvent)} * @param serverAddress the server the netty channel binds to * @param inUseEvent a connection listener registered with a {@link NettyConnection} when created */ - void afterAcquiredOrCreated( BoltServerAddress serverAddress, ListenerEvent inUseEvent ); + void afterConnectionCreated( BoltServerAddress serverAddress, ListenerEvent inUseEvent ); /** * After releasing a netty channel back to pool successfully * @param serverAddress the server the netty channel binds to * @param inUseEvent a connection listener registered with a {@link NettyConnection} when destroyed */ - void afterReleased( BoltServerAddress serverAddress, ListenerEvent inUseEvent ); + void afterConnectionReleased( BoltServerAddress serverAddress, ListenerEvent inUseEvent ); ListenerEvent createListenerEvent(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/spi/ConnectionPoolMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/spi/ConnectionPoolMetrics.java index 40a8afddab..0d3e4b7c90 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/spi/ConnectionPoolMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/spi/ConnectionPoolMetrics.java @@ -18,6 +18,10 @@ */ package org.neo4j.driver.internal.metrics.spi; +import java.util.concurrent.TimeUnit; + +import org.neo4j.driver.v1.Config; + public interface ConnectionPoolMetrics { /** @@ -27,55 +31,74 @@ public interface ConnectionPoolMetrics String uniqueName(); /** - * The status of the pool - * @return The status of the pool in a string + * The status of the pool. + * @return The status of the pool. */ PoolStatus poolStatus(); /** - * The amount of connections that is in-use (borrowed out of the pool). - * The number is changing up and down from time to time. - * @return The amount of connections that is in-use + * The amount of channels that are currently in-use (borrowed out of the pool). + * @return The amount of channels that are currently in-use */ int inUse(); /** - * The amount of connections that is idle (buffered inside the pool). - * The number is changing up and down from time to time. - * @return The amount of connections that is idle. + * The amount of channels that are currently idle (buffered inside the pool). + * @return The amount of channels that are currently idle. */ int idle(); /** - * The amount of connections that is going to be created. - * The amount is increased by one when the pool noticed a request to create a new connection. - * The amount is decreased by one when the pool noticed a new connection is created regardless successfully or not. - * The number is changing up and down from time to time. - * @return The amount of connection that is creating. + * The amount of channels that are currently waiting to be created. + * The amount is increased by one when the pool noticed a request to create a new channel. + * The amount is decreased by one when the pool noticed a new channel is created successfully or failed to create. + * @return The amount of channels that are waiting to be created. */ int creating(); /** - * An increasing-only number to record how many connections have been created by this pool successfully. - * @return The amount of connections have ever been created by this pool. + * An increasing-only number to record how many channels have been created by this pool successfully. + * @return The amount of channels have ever been created by this pool. */ long created(); /** - * An increasing-only number to record how many connections have been failed to create. - * @return The amount of connections have been failed to create by this pool. + * An increasing-only number to record how many channels have been failed to create. + * @return The amount of channels have been failed to create by this pool. */ long failedToCreate(); /** - * An increasing-only number to record how many connections have been closed by this pool. - * @return The amount of connections have been closed by this pool. + * An increasing-only number to record how many channels have been closed by this pool. + * @return The amount of channels have been closed by this pool. */ long closed(); + /** + * The current count of application requests to wait for acquiring a connection from the pool. + * The reason to wait could be waiting for creating a new channel, or waiting for a channel to be free by application when the pool is full. + * @return The current amount of application request to wait for acquiring a connection from the pool. + */ + int acquiring(); + + /** + * An increasing-only number to record how many connections have been acquired from the pool + * The connections acquired could hold either a newly created channel or a reused channel from the pool. + * @return The amount of connections that have been acquired from the pool. + */ + long acquired(); + + /** + * An increasing-only number to record how many times that we've failed to acquire a connection from the pool within configured maximum acquisition timeout + * set by {@link Config.ConfigBuilder#withConnectionAcquisitionTimeout(long, TimeUnit)}. + * The connection acquired could hold either a newly created channel or a reused channel from the pool. + * @return The amount of failures to acquire a connection from the pool within maximum connection acquisition timeout. + */ + long timedOutToAcquire(); + /** * An acquisition time histogram records how long it takes to acquire an connection from this pool. - * The connection acquired from the pool could either be a connection idling inside the pool or a connection created by the pool. + * The connection acquired from the pool could contain either a channel idling inside the pool or a channel created by the pool. * @return The acquisition time histogram. */ Histogram acquisitionTimeHistogram(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/spi/PoolStatus.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/spi/PoolStatus.java index 6fe7099805..2a32d9242d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/spi/PoolStatus.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/spi/PoolStatus.java @@ -20,5 +20,18 @@ public enum PoolStatus { - Open, Closed + OPEN( 0 ), + CLOSED( 1 ); + + private final int value; + + PoolStatus( int value ) + { + this.value = value; + } + + public int value() + { + return value; + } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionPool.java b/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionPool.java index 73c7f6d86b..2ffb40c402 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionPool.java +++ b/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionPool.java @@ -35,5 +35,5 @@ public interface ConnectionPool CompletionStage close(); - boolean isOpen(); + boolean isOpen( BoltServerAddress address ); } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java similarity index 99% rename from driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplTest.java rename to driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java index 3f4f9dde66..ee280d4d1f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java @@ -62,7 +62,7 @@ import static org.neo4j.driver.internal.metrics.InternalAbstractMetrics.DEV_NULL_METRICS; import static org.neo4j.driver.v1.util.TestUtil.await; -public class ConnectionPoolImplTest +public class ConnectionPoolImplIT { private static final BoltServerAddress ADDRESS_1 = new BoltServerAddress( "server:1" ); private static final BoltServerAddress ADDRESS_2 = new BoltServerAddress( "server:2" ); diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java similarity index 97% rename from driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolTest.java rename to driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java index 93ce7774c7..6648131e99 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java @@ -47,12 +47,14 @@ import org.neo4j.driver.v1.util.TestNeo4j; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -60,7 +62,7 @@ import static org.neo4j.driver.internal.metrics.InternalAbstractMetrics.DEV_NULL_METRICS; import static org.neo4j.driver.v1.Values.value; -public class NettyChannelPoolTest +public class NettyChannelPoolIT { @Rule public final TestNeo4j neo4j = new TestNeo4j(); @@ -100,7 +102,7 @@ public void shouldAcquireAndReleaseWithCorrectCredentials() throws Exception assertTrue( acquireFuture.isSuccess() ); Channel channel = acquireFuture.getNow(); assertNotNull( channel ); - verify( poolHandler ).channelCreated( channel ); + verify( poolHandler ).channelCreated( argThat( is( channel ) ), any() ); verify( poolHandler, never() ).channelReleased( channel ); Future releaseFuture = pool.release( channel ); diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelTrackerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelTrackerTest.java index 122478543e..51aaa35102 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelTrackerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelTrackerTest.java @@ -44,7 +44,7 @@ public void shouldIncrementInUseCountWhenChannelCreated() assertEquals( 0, tracker.inUseChannelCount( address ) ); assertEquals( 0, tracker.idleChannelCount( address ) ); - tracker.channelCreated( channel ); + tracker.channelCreated( channel, null ); assertEquals( 1, tracker.inUseChannelCount( address ) ); assertEquals( 0, tracker.idleChannelCount( address ) ); } @@ -56,7 +56,7 @@ public void shouldIncrementInUseCountWhenChannelAcquired() assertEquals( 0, tracker.inUseChannelCount( address ) ); assertEquals( 0, tracker.idleChannelCount( address ) ); - tracker.channelCreated( channel ); + tracker.channelCreated( channel, null ); assertEquals( 1, tracker.inUseChannelCount( address ) ); assertEquals( 0, tracker.idleChannelCount( address ) ); @@ -77,11 +77,11 @@ public void shouldIncrementInuseCountForAddress() Channel channel3 = newChannel(); assertEquals( 0, tracker.inUseChannelCount( address ) ); - tracker.channelCreated( channel1 ); + tracker.channelCreated( channel1, null ); assertEquals( 1, tracker.inUseChannelCount( address ) ); - tracker.channelCreated( channel2 ); + tracker.channelCreated( channel2, null ); assertEquals( 2, tracker.inUseChannelCount( address ) ); - tracker.channelCreated( channel3 ); + tracker.channelCreated( channel3, null ); assertEquals( 3, tracker.inUseChannelCount( address ) ); assertEquals( 0, tracker.idleChannelCount( address ) ); } @@ -93,9 +93,9 @@ public void shouldDecrementCountForAddress() Channel channel2 = newChannel(); Channel channel3 = newChannel(); - tracker.channelCreated( channel1 ); - tracker.channelCreated( channel2 ); - tracker.channelCreated( channel3 ); + tracker.channelCreated( channel1, null ); + tracker.channelCreated( channel2, null ); + tracker.channelCreated( channel3, null ); assertEquals( 3, tracker.inUseChannelCount( address ) ); assertEquals( 0, tracker.idleChannelCount( address ) ); diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/FailingConnectionDriverFactory.java b/driver/src/test/java/org/neo4j/driver/internal/util/FailingConnectionDriverFactory.java index cdb4e27305..31dbd58aa3 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/FailingConnectionDriverFactory.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/FailingConnectionDriverFactory.java @@ -95,9 +95,9 @@ public CompletionStage close() } @Override - public boolean isOpen() + public boolean isOpen( BoltServerAddress address ) { - return delegate.isOpen(); + return delegate.isOpen( address ); } }