View Javadoc
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  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.concurrent.locks.ReentrantLock;
21  
22  /**
23   * @author Clinton Begin
24   */
25  public class PoolState {
26  
27    // This lock does not guarantee consistency.
28    // Field values can be modified in PooledDataSource
29    // after the instance is returned from
30    // PooledDataSource#getPoolState().
31    // A possible fix is to create and return a 'snapshot'.
32    private final ReentrantLock lock = new ReentrantLock();
33  
34    protected PooledDataSource dataSource;
35  
36    protected final List<PooledConnection> idleConnections = new ArrayList<>();
37    protected final List<PooledConnection> activeConnections = new ArrayList<>();
38    protected long requestCount;
39    protected long accumulatedRequestTime;
40    protected long accumulatedCheckoutTime;
41    protected long claimedOverdueConnectionCount;
42    protected long accumulatedCheckoutTimeOfOverdueConnections;
43    protected long accumulatedWaitTime;
44    protected long hadToWaitCount;
45    protected long badConnectionCount;
46  
47    public PoolState(PooledDataSource dataSource) {
48      this.dataSource = dataSource;
49    }
50  
51    public long getRequestCount() {
52      lock.lock();
53      try {
54        return requestCount;
55      } finally {
56        lock.unlock();
57      }
58    }
59  
60    public long getAverageRequestTime() {
61      lock.lock();
62      try {
63        return requestCount == 0 ? 0 : accumulatedRequestTime / requestCount;
64      } finally {
65        lock.unlock();
66      }
67    }
68  
69    public long getAverageWaitTime() {
70      lock.lock();
71      try {
72        return hadToWaitCount == 0 ? 0 : accumulatedWaitTime / hadToWaitCount;
73      } finally {
74        lock.unlock();
75      }
76    }
77  
78    public long getHadToWaitCount() {
79      lock.lock();
80      try {
81        return hadToWaitCount;
82      } finally {
83        lock.unlock();
84      }
85    }
86  
87    public long getBadConnectionCount() {
88      lock.lock();
89      try {
90        return badConnectionCount;
91      } finally {
92        lock.unlock();
93      }
94    }
95  
96    public long getClaimedOverdueConnectionCount() {
97      lock.lock();
98      try {
99        return claimedOverdueConnectionCount;
100     } finally {
101       lock.unlock();
102     }
103   }
104 
105   public long getAverageOverdueCheckoutTime() {
106     lock.lock();
107     try {
108       return claimedOverdueConnectionCount == 0 ? 0
109           : accumulatedCheckoutTimeOfOverdueConnections / claimedOverdueConnectionCount;
110     } finally {
111       lock.unlock();
112     }
113   }
114 
115   public long getAverageCheckoutTime() {
116     lock.lock();
117     try {
118       return requestCount == 0 ? 0 : accumulatedCheckoutTime / requestCount;
119     } finally {
120       lock.unlock();
121     }
122   }
123 
124   public int getIdleConnectionCount() {
125     lock.lock();
126     try {
127       return idleConnections.size();
128     } finally {
129       lock.unlock();
130     }
131   }
132 
133   public int getActiveConnectionCount() {
134     lock.lock();
135     try {
136       return activeConnections.size();
137     } finally {
138       lock.unlock();
139     }
140   }
141 
142   @Override
143   public String toString() {
144     lock.lock();
145     try {
146       StringBuilder builder = new StringBuilder();
147       builder.append("\n===CONFIGURATION==============================================");
148       builder.append("\n jdbcDriver                     ").append(dataSource.getDriver());
149       builder.append("\n jdbcUrl                        ").append(dataSource.getUrl());
150       builder.append("\n jdbcUsername                   ").append(dataSource.getUsername());
151       builder.append("\n jdbcPassword                   ")
152           .append(dataSource.getPassword() == null ? "NULL" : "************");
153       builder.append("\n poolMaxActiveConnections       ").append(dataSource.poolMaximumActiveConnections);
154       builder.append("\n poolMaxIdleConnections         ").append(dataSource.poolMaximumIdleConnections);
155       builder.append("\n poolMaxCheckoutTime            ").append(dataSource.poolMaximumCheckoutTime);
156       builder.append("\n poolTimeToWait                 ").append(dataSource.poolTimeToWait);
157       builder.append("\n poolPingEnabled                ").append(dataSource.poolPingEnabled);
158       builder.append("\n poolPingQuery                  ").append(dataSource.poolPingQuery);
159       builder.append("\n poolPingConnectionsNotUsedFor  ").append(dataSource.poolPingConnectionsNotUsedFor);
160       builder.append("\n ---STATUS-----------------------------------------------------");
161       builder.append("\n activeConnections              ").append(getActiveConnectionCount());
162       builder.append("\n idleConnections                ").append(getIdleConnectionCount());
163       builder.append("\n requestCount                   ").append(getRequestCount());
164       builder.append("\n averageRequestTime             ").append(getAverageRequestTime());
165       builder.append("\n averageCheckoutTime            ").append(getAverageCheckoutTime());
166       builder.append("\n claimedOverdue                 ").append(getClaimedOverdueConnectionCount());
167       builder.append("\n averageOverdueCheckoutTime     ").append(getAverageOverdueCheckoutTime());
168       builder.append("\n hadToWait                      ").append(getHadToWaitCount());
169       builder.append("\n averageWaitTime                ").append(getAverageWaitTime());
170       builder.append("\n badConnectionCount             ").append(getBadConnectionCount());
171       builder.append("\n===============================================================");
172       return builder.toString();
173     } finally {
174       lock.unlock();
175     }
176   }
177 
178 }