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