001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.pool2.impl; 018 019import java.io.OutputStreamWriter; 020import java.io.PrintWriter; 021import java.nio.charset.Charset; 022import java.time.Duration; 023 024import org.apache.commons.pool2.TrackedUse; 025import org.apache.commons.pool2.UsageTracking; 026 027/** 028 * Configuration settings for abandoned object removal. 029 * 030 * @since 2.0 031 */ 032public class AbandonedConfig { 033 034 /** 035 * The 5 minutes Duration. 036 */ 037 private static final Duration DEFAULT_REMOVE_ABANDONED_TIMEOUT_DURATION = Duration.ofMinutes(5); 038 039 /** 040 * Creates a new instance with values from the given instance. 041 * 042 * @param abandonedConfig the source, may be null. 043 * @return A new instance or null if the input is null. 044 * @since 2.11.0 045 */ 046 public static AbandonedConfig copy(final AbandonedConfig abandonedConfig) { 047 return abandonedConfig == null ? null : new AbandonedConfig(abandonedConfig); 048 } 049 050 /** 051 * Whether or not borrowObject performs abandoned object removal. 052 */ 053 private boolean removeAbandonedOnBorrow; 054 055 /** 056 * Whether or not pool maintenance (evictor) performs abandoned object 057 * removal. 058 */ 059 private boolean removeAbandonedOnMaintenance; 060 061 /** 062 * Timeout before an abandoned object can be removed. 063 */ 064 private Duration removeAbandonedTimeoutDuration = DEFAULT_REMOVE_ABANDONED_TIMEOUT_DURATION; 065 066 /** 067 * Determines whether or not to log stack traces for application code 068 * which abandoned an object. 069 */ 070 private boolean logAbandoned; 071 072 /** 073 * Determines whether or not to log full stack traces when logAbandoned is true. 074 * If disabled, then a faster method for logging stack traces with only class data 075 * may be used if possible. 076 * 077 * @since 2.5 078 */ 079 private boolean requireFullStackTrace = true; 080 081 /** 082 * PrintWriter to use to log information on abandoned objects. 083 * Use of default system encoding is deliberate. 084 */ 085 private PrintWriter logWriter = new PrintWriter(new OutputStreamWriter(System.out, Charset.defaultCharset())); 086 087 /** 088 * If the pool implements {@link UsageTracking}, should the pool record a 089 * stack trace every time a method is called on a pooled object and retain 090 * the most recent stack trace to aid debugging of abandoned objects? 091 */ 092 private boolean useUsageTracking; 093 094 /** 095 * Creates a new instance. 096 */ 097 public AbandonedConfig() { 098 // empty 099 } 100 101 /** 102 * Creates a new instance with values from the given instance. 103 * 104 * @param abandonedConfig the source. 105 */ 106 @SuppressWarnings("resource") 107 private AbandonedConfig(final AbandonedConfig abandonedConfig) { 108 this.setLogAbandoned(abandonedConfig.getLogAbandoned()); 109 this.setLogWriter(abandonedConfig.getLogWriter()); 110 this.setRemoveAbandonedOnBorrow(abandonedConfig.getRemoveAbandonedOnBorrow()); 111 this.setRemoveAbandonedOnMaintenance(abandonedConfig.getRemoveAbandonedOnMaintenance()); 112 this.setRemoveAbandonedTimeout(abandonedConfig.getRemoveAbandonedTimeoutDuration()); 113 this.setUseUsageTracking(abandonedConfig.getUseUsageTracking()); 114 this.setRequireFullStackTrace(abandonedConfig.getRequireFullStackTrace()); 115 } 116 117 /** 118 * Flag to log stack traces for application code which abandoned 119 * an object. 120 * 121 * Defaults to false. 122 * Logging of abandoned objects adds overhead for every object created 123 * because a stack trace has to be generated. 124 * 125 * @return boolean true if stack trace logging is turned on for abandoned 126 * objects 127 * 128 */ 129 public boolean getLogAbandoned() { 130 return this.logAbandoned; 131 } 132 133 /** 134 * Gets the log writer being used by this configuration to log 135 * information on abandoned objects. If not set, a PrintWriter based on 136 * System.out with the system default encoding is used. 137 * 138 * @return log writer in use 139 */ 140 public PrintWriter getLogWriter() { 141 return logWriter; 142 } 143 144 /** 145 * <p>Flag to remove abandoned objects if they exceed the 146 * removeAbandonedTimeout when borrowObject is invoked.</p> 147 * 148 * <p>The default value is false.</p> 149 * 150 * <p>If set to true, abandoned objects are removed by borrowObject if 151 * there are fewer than 2 idle objects available in the pool and 152 * {@code getNumActive() > getMaxTotal() - 3}</p> 153 * 154 * @return true if abandoned objects are to be removed by borrowObject 155 */ 156 public boolean getRemoveAbandonedOnBorrow() { 157 return this.removeAbandonedOnBorrow; 158 } 159 160 /** 161 * <p>Flag to remove abandoned objects if they exceed the 162 * removeAbandonedTimeout when pool maintenance (the "evictor") 163 * runs.</p> 164 * 165 * <p>The default value is false.</p> 166 * 167 * <p>If set to true, abandoned objects are removed by the pool 168 * maintenance thread when it runs. This setting has no effect 169 * unless maintenance is enabled by setting 170 * {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis()} 171 * to a positive number.</p> 172 * 173 * @return true if abandoned objects are to be removed by the evictor 174 */ 175 public boolean getRemoveAbandonedOnMaintenance() { 176 return this.removeAbandonedOnMaintenance; 177 } 178 179 /** 180 * <p>Timeout in seconds before an abandoned object can be removed.</p> 181 * 182 * <p>The time of most recent use of an object is the maximum (latest) of 183 * {@link TrackedUse#getLastUsedInstant()} (if this class of the object implements 184 * TrackedUse) and the time when the object was borrowed from the pool.</p> 185 * 186 * <p>The default value is 300 seconds.</p> 187 * 188 * @return the abandoned object timeout in seconds. 189 * @deprecated Use {@link #getRemoveAbandonedTimeoutDuration()}. 190 */ 191 @Deprecated 192 public int getRemoveAbandonedTimeout() { 193 return (int) this.removeAbandonedTimeoutDuration.getSeconds(); 194 } 195 196 /** 197 * <p>Timeout before an abandoned object can be removed.</p> 198 * 199 * <p>The time of most recent use of an object is the maximum (latest) of 200 * {@link TrackedUse#getLastUsedInstant()} (if this class of the object implements 201 * TrackedUse) and the time when the object was borrowed from the pool.</p> 202 * 203 * <p>The default value is 300 seconds.</p> 204 * 205 * @return the abandoned object timeout. 206 * @since 2.10.0 207 */ 208 public Duration getRemoveAbandonedTimeoutDuration() { 209 return this.removeAbandonedTimeoutDuration; 210 } 211 212 /** 213 * Indicates if full stack traces are required when {@link #getLogAbandoned() logAbandoned} 214 * is true. Defaults to true. Logging of abandoned objects requiring a full stack trace will 215 * generate an entire stack trace to generate for every object created. If this is disabled, 216 * a faster but less informative stack walking mechanism may be used if available. 217 * 218 * @return true if full stack traces are required for logging abandoned connections, or false 219 * if abbreviated stack traces are acceptable 220 * @see CallStack 221 * @since 2.5 222 */ 223 public boolean getRequireFullStackTrace() { 224 return requireFullStackTrace; 225 } 226 227 /** 228 * If the pool implements {@link UsageTracking}, should the pool record a 229 * stack trace every time a method is called on a pooled object and retain 230 * the most recent stack trace to aid debugging of abandoned objects? 231 * 232 * @return {@code true} if usage tracking is enabled 233 */ 234 public boolean getUseUsageTracking() { 235 return useUsageTracking; 236 } 237 238 /** 239 * Sets the flag to log stack traces for application code which abandoned 240 * an object. 241 * 242 * @param logAbandoned true turns on abandoned stack trace logging 243 * @see #getLogAbandoned() 244 * 245 */ 246 public void setLogAbandoned(final boolean logAbandoned) { 247 this.logAbandoned = logAbandoned; 248 } 249 250 /** 251 * Sets the log writer to be used by this configuration to log 252 * information on abandoned objects. 253 * 254 * @param logWriter The new log writer 255 */ 256 public void setLogWriter(final PrintWriter logWriter) { 257 this.logWriter = logWriter; 258 } 259 260 /** 261 * Flag to remove abandoned objects if they exceed the 262 * removeAbandonedTimeout when borrowObject is invoked. 263 * 264 * @param removeAbandonedOnBorrow true means abandoned objects will be 265 * removed by borrowObject 266 * @see #getRemoveAbandonedOnBorrow() 267 */ 268 public void setRemoveAbandonedOnBorrow(final boolean removeAbandonedOnBorrow) { 269 this.removeAbandonedOnBorrow = removeAbandonedOnBorrow; 270 } 271 272 /** 273 * Flag to remove abandoned objects if they exceed the 274 * removeAbandonedTimeout when pool maintenance runs. 275 * 276 * @param removeAbandonedOnMaintenance true means abandoned objects will be 277 * removed by pool maintenance 278 * @see #getRemoveAbandonedOnMaintenance 279 */ 280 public void setRemoveAbandonedOnMaintenance(final boolean removeAbandonedOnMaintenance) { 281 this.removeAbandonedOnMaintenance = removeAbandonedOnMaintenance; 282 } 283 284 /** 285 * Sets the timeout before an abandoned object can be 286 * removed. 287 * 288 * <p>Setting this property has no effect if 289 * {@link #getRemoveAbandonedOnBorrow() removeAbandonedOnBorrow} and 290 * {@link #getRemoveAbandonedOnMaintenance() removeAbandonedOnMaintenance} 291 * are both false.</p> 292 * 293 * @param removeAbandonedTimeout new abandoned timeout 294 * @see #getRemoveAbandonedTimeoutDuration() 295 * @since 2.10.0 296 */ 297 public void setRemoveAbandonedTimeout(final Duration removeAbandonedTimeout) { 298 this.removeAbandonedTimeoutDuration = PoolImplUtils.nonNull(removeAbandonedTimeout, DEFAULT_REMOVE_ABANDONED_TIMEOUT_DURATION); 299 } 300 301 /** 302 * Sets the timeout in seconds before an abandoned object can be 303 * removed. 304 * 305 * <p>Setting this property has no effect if 306 * {@link #getRemoveAbandonedOnBorrow() removeAbandonedOnBorrow} and 307 * {@link #getRemoveAbandonedOnMaintenance() removeAbandonedOnMaintenance} 308 * are both false.</p> 309 * 310 * @param removeAbandonedTimeoutSeconds new abandoned timeout in seconds 311 * @see #getRemoveAbandonedTimeoutDuration() 312 * @deprecated Use {@link #setRemoveAbandonedTimeout(Duration)}. 313 */ 314 @Deprecated 315 public void setRemoveAbandonedTimeout(final int removeAbandonedTimeoutSeconds) { 316 setRemoveAbandonedTimeout(Duration.ofSeconds(removeAbandonedTimeoutSeconds)); 317 } 318 319 /** 320 * Sets the flag to require full stack traces for logging abandoned connections when enabled. 321 * 322 * @param requireFullStackTrace indicates whether or not full stack traces are required in 323 * abandoned connection logs 324 * @see CallStack 325 * @see #getRequireFullStackTrace() 326 * @since 2.5 327 */ 328 public void setRequireFullStackTrace(final boolean requireFullStackTrace) { 329 this.requireFullStackTrace = requireFullStackTrace; 330 } 331 332 /** 333 * If the pool implements {@link UsageTracking}, configure whether the pool 334 * should record a stack trace every time a method is called on a pooled 335 * object and retain the most recent stack trace to aid debugging of 336 * abandoned objects. 337 * 338 * @param useUsageTracking A value of {@code true} will enable 339 * the recording of a stack trace on every use 340 * of a pooled object 341 */ 342 public void setUseUsageTracking(final boolean useUsageTracking) { 343 this.useUsageTracking = useUsageTracking; 344 } 345 346 /** 347 * @since 2.4.3 348 */ 349 @Override 350 public String toString() { 351 final StringBuilder builder = new StringBuilder(); 352 builder.append("AbandonedConfig [removeAbandonedOnBorrow="); 353 builder.append(removeAbandonedOnBorrow); 354 builder.append(", removeAbandonedOnMaintenance="); 355 builder.append(removeAbandonedOnMaintenance); 356 builder.append(", removeAbandonedTimeoutDuration="); 357 builder.append(removeAbandonedTimeoutDuration); 358 builder.append(", logAbandoned="); 359 builder.append(logAbandoned); 360 builder.append(", logWriter="); 361 builder.append(logWriter); 362 builder.append(", useUsageTracking="); 363 builder.append(useUsageTracking); 364 builder.append("]"); 365 return builder.toString(); 366 } 367}