PoolState.java

  1. /*
  2.  *    Copyright 2009-2024 the original author or authors.
  3.  *
  4.  *    Licensed under the Apache License, Version 2.0 (the "License");
  5.  *    you may not use this file except in compliance with the License.
  6.  *    You may obtain a copy of the License at
  7.  *
  8.  *       https://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  *    Unless required by applicable law or agreed to in writing, software
  11.  *    distributed under the License is distributed on an "AS IS" BASIS,
  12.  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  *    See the License for the specific language governing permissions and
  14.  *    limitations under the License.
  15.  */
  16. package org.apache.ibatis.datasource.pooled;

  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import java.util.concurrent.locks.ReentrantLock;

  20. /**
  21.  * @author Clinton Begin
  22.  */
  23. public class PoolState {

  24.   // This lock does not guarantee consistency.
  25.   // Field values can be modified in PooledDataSource
  26.   // after the instance is returned from
  27.   // PooledDataSource#getPoolState().
  28.   // A possible fix is to create and return a 'snapshot'.
  29.   private final ReentrantLock lock = new ReentrantLock();

  30.   protected PooledDataSource dataSource;

  31.   protected final List<PooledConnection> idleConnections = new ArrayList<>();
  32.   protected final List<PooledConnection> activeConnections = new ArrayList<>();
  33.   protected long requestCount;
  34.   protected long accumulatedRequestTime;
  35.   protected long accumulatedCheckoutTime;
  36.   protected long claimedOverdueConnectionCount;
  37.   protected long accumulatedCheckoutTimeOfOverdueConnections;
  38.   protected long accumulatedWaitTime;
  39.   protected long hadToWaitCount;
  40.   protected long badConnectionCount;

  41.   public PoolState(PooledDataSource dataSource) {
  42.     this.dataSource = dataSource;
  43.   }

  44.   public long getRequestCount() {
  45.     lock.lock();
  46.     try {
  47.       return requestCount;
  48.     } finally {
  49.       lock.unlock();
  50.     }
  51.   }

  52.   public long getAverageRequestTime() {
  53.     lock.lock();
  54.     try {
  55.       return requestCount == 0 ? 0 : accumulatedRequestTime / requestCount;
  56.     } finally {
  57.       lock.unlock();
  58.     }
  59.   }

  60.   public long getAverageWaitTime() {
  61.     lock.lock();
  62.     try {
  63.       return hadToWaitCount == 0 ? 0 : accumulatedWaitTime / hadToWaitCount;
  64.     } finally {
  65.       lock.unlock();
  66.     }
  67.   }

  68.   public long getHadToWaitCount() {
  69.     lock.lock();
  70.     try {
  71.       return hadToWaitCount;
  72.     } finally {
  73.       lock.unlock();
  74.     }
  75.   }

  76.   public long getBadConnectionCount() {
  77.     lock.lock();
  78.     try {
  79.       return badConnectionCount;
  80.     } finally {
  81.       lock.unlock();
  82.     }
  83.   }

  84.   public long getClaimedOverdueConnectionCount() {
  85.     lock.lock();
  86.     try {
  87.       return claimedOverdueConnectionCount;
  88.     } finally {
  89.       lock.unlock();
  90.     }
  91.   }

  92.   public long getAverageOverdueCheckoutTime() {
  93.     lock.lock();
  94.     try {
  95.       return claimedOverdueConnectionCount == 0 ? 0
  96.           : accumulatedCheckoutTimeOfOverdueConnections / claimedOverdueConnectionCount;
  97.     } finally {
  98.       lock.unlock();
  99.     }
  100.   }

  101.   public long getAverageCheckoutTime() {
  102.     lock.lock();
  103.     try {
  104.       return requestCount == 0 ? 0 : accumulatedCheckoutTime / requestCount;
  105.     } finally {
  106.       lock.unlock();
  107.     }
  108.   }

  109.   public int getIdleConnectionCount() {
  110.     lock.lock();
  111.     try {
  112.       return idleConnections.size();
  113.     } finally {
  114.       lock.unlock();
  115.     }
  116.   }

  117.   public int getActiveConnectionCount() {
  118.     lock.lock();
  119.     try {
  120.       return activeConnections.size();
  121.     } finally {
  122.       lock.unlock();
  123.     }
  124.   }

  125.   @Override
  126.   public String toString() {
  127.     lock.lock();
  128.     try {
  129.       StringBuilder builder = new StringBuilder();
  130.       builder.append("\n===CONFIGURATION==============================================");
  131.       builder.append("\n jdbcDriver                     ").append(dataSource.getDriver());
  132.       builder.append("\n jdbcUrl                        ").append(dataSource.getUrl());
  133.       builder.append("\n jdbcUsername                   ").append(dataSource.getUsername());
  134.       builder.append("\n jdbcPassword                   ")
  135.           .append(dataSource.getPassword() == null ? "NULL" : "************");
  136.       builder.append("\n poolMaxActiveConnections       ").append(dataSource.poolMaximumActiveConnections);
  137.       builder.append("\n poolMaxIdleConnections         ").append(dataSource.poolMaximumIdleConnections);
  138.       builder.append("\n poolMaxCheckoutTime            ").append(dataSource.poolMaximumCheckoutTime);
  139.       builder.append("\n poolTimeToWait                 ").append(dataSource.poolTimeToWait);
  140.       builder.append("\n poolPingEnabled                ").append(dataSource.poolPingEnabled);
  141.       builder.append("\n poolPingQuery                  ").append(dataSource.poolPingQuery);
  142.       builder.append("\n poolPingConnectionsNotUsedFor  ").append(dataSource.poolPingConnectionsNotUsedFor);
  143.       builder.append("\n ---STATUS-----------------------------------------------------");
  144.       builder.append("\n activeConnections              ").append(getActiveConnectionCount());
  145.       builder.append("\n idleConnections                ").append(getIdleConnectionCount());
  146.       builder.append("\n requestCount                   ").append(getRequestCount());
  147.       builder.append("\n averageRequestTime             ").append(getAverageRequestTime());
  148.       builder.append("\n averageCheckoutTime            ").append(getAverageCheckoutTime());
  149.       builder.append("\n claimedOverdue                 ").append(getClaimedOverdueConnectionCount());
  150.       builder.append("\n averageOverdueCheckoutTime     ").append(getAverageOverdueCheckoutTime());
  151.       builder.append("\n hadToWait                      ").append(getHadToWaitCount());
  152.       builder.append("\n averageWaitTime                ").append(getAverageWaitTime());
  153.       builder.append("\n badConnectionCount             ").append(getBadConnectionCount());
  154.       builder.append("\n===============================================================");
  155.       return builder.toString();
  156.     } finally {
  157.       lock.unlock();
  158.     }
  159.   }

  160. }