NettyChannelTracker implements ChannelPoolHandler { public void prepareToCloseChannels() { for ( Channel channel : allChannels ) { BoltProtocol protocol = BoltProtocol.forChannel( channel ); try { protocol.prepareToCloseChannel( channel ); } catch ( Throwable e ) { log.debug( "Failed to prepare to close Channel %s due to error %s. " + "It is safe to ignore this error as the channel will be closed despite if it is successfully prepared to close or not.", channel, e.getMessage() ); } } } NettyChannelTracker( MetricsListener metricsListener, EventExecutor eventExecutor, Logging logging );  NettyChannelTracker( MetricsListener metricsListener, ChannelGroup channels, Logging logging ); @Override void channelReleased( Channel channel ); @Override void channelAcquired( Channel channel ); @Override void channelCreated( Channel channel ); void channelCreated( Channel channel, ListenerEvent creatingEvent ); ListenerEvent channelCreating( String poolId ); void channelFailedToCreate( String poolId ); void channelClosed( Channel channel ); int inUseChannelCount( BoltServerAddress address ); int idleChannelCount( BoltServerAddress address ); void prepareToCloseChannels();  }
@Test void shouldDelegateToProtocolPrepareToClose() { EmbeddedChannel channel = newChannelWithProtocolV3(); EmbeddedChannel anotherChannel = newChannelWithProtocolV3(); ChannelGroup group = mock( ChannelGroup.class ); when( group.iterator() ).thenReturn( new Arrays.Iterator<>( new Channel[]{channel, anotherChannel} ) ); NettyChannelTracker tracker = new NettyChannelTracker( DEV_NULL_METRICS, group, DEV_NULL_LOGGING ); tracker.prepareToCloseChannels(); assertThat( channel.outboundMessages().size(), equalTo( 1 ) ); assertThat( channel.outboundMessages(), hasItem( GoodbyeMessage.GOODBYE ) ); assertThat( anotherChannel.outboundMessages().size(), equalTo( 1 ) ); assertThat( anotherChannel.outboundMessages(), hasItem( GoodbyeMessage.GOODBYE ) ); }