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 org.apache.commons.pool2.TrackedUse;
021import org.apache.commons.pool2.UsageTracking;
022
023import java.io.PrintWriter;
024
025/**
026 * Configuration settings for abandoned object removal.
027 *
028 * @since 2.0
029 */
030public class AbandonedConfig {
031
032    /**
033     * Whether or not borrowObject performs abandoned object removal.
034     */
035    private boolean removeAbandonedOnBorrow = false;
036
037    /**
038     * <p>Flag to remove abandoned objects if they exceed the
039     * removeAbandonedTimeout when borrowObject is invoked.</p>
040     *
041     * <p>The default value is false.</p>
042     *
043     * <p>If set to true, abandoned objects are removed by borrowObject if
044     * there are fewer than 2 idle objects available in the pool and
045     * <code>getNumActive() &gt; getMaxTotal() - 3</code></p>
046     *
047     * @return true if abandoned objects are to be removed by borrowObject
048     */
049    public boolean getRemoveAbandonedOnBorrow() {
050        return this.removeAbandonedOnBorrow;
051    }
052
053    /**
054     * <p>Flag to remove abandoned objects if they exceed the
055     * removeAbandonedTimeout when borrowObject is invoked.</p>
056     *
057     * @param removeAbandonedOnBorrow true means abandoned objects will be
058     *   removed by borrowObject
059     * @see #getRemoveAbandonedOnBorrow()
060     */
061    public void setRemoveAbandonedOnBorrow(final boolean removeAbandonedOnBorrow) {
062        this.removeAbandonedOnBorrow = removeAbandonedOnBorrow;
063    }
064
065    /**
066     * Whether or not pool maintenance (evictor) performs abandoned object
067     * removal.
068     */
069    private boolean removeAbandonedOnMaintenance = false;
070
071    /**
072     * <p>Flag to remove abandoned objects if they exceed the
073     * removeAbandonedTimeout when pool maintenance (the "evictor")
074     * runs.</p>
075     *
076     * <p>The default value is false.</p>
077     *
078     * <p>If set to true, abandoned objects are removed by the pool
079     * maintenance thread when it runs.  This setting has no effect
080     * unless maintenance is enabled by setting
081     *{@link GenericObjectPool#getTimeBetweenEvictionRunsMillis() timeBetweenEvictionRunsMillis}
082     * to a positive number.</p>
083     *
084     * @return true if abandoned objects are to be removed by the evictor
085     */
086    public boolean getRemoveAbandonedOnMaintenance() {
087        return this.removeAbandonedOnMaintenance;
088    }
089
090    /**
091     * <p>Flag to remove abandoned objects if they exceed the
092     * removeAbandonedTimeout when pool maintenance runs.</p>
093     *
094     * @param removeAbandonedOnMaintenance true means abandoned objects will be
095     *   removed by pool maintenance
096     * @see #getRemoveAbandonedOnMaintenance
097     */
098    public void setRemoveAbandonedOnMaintenance(final boolean removeAbandonedOnMaintenance) {
099        this.removeAbandonedOnMaintenance = removeAbandonedOnMaintenance;
100    }
101
102    /**
103     * Timeout in seconds before an abandoned object can be removed.
104     */
105    private int removeAbandonedTimeout = 300;
106
107    /**
108     * <p>Timeout in seconds before an abandoned object can be removed.</p>
109     *
110     * <p>The time of most recent use of an object is the maximum (latest) of
111     * {@link TrackedUse#getLastUsed()} (if this class of the object implements
112     * TrackedUse) and the time when the object was borrowed from the pool.</p>
113     *
114     * <p>The default value is 300 seconds.</p>
115     *
116     * @return the abandoned object timeout in seconds
117     */
118    public int getRemoveAbandonedTimeout() {
119        return this.removeAbandonedTimeout;
120    }
121
122    /**
123     * <p>Sets the timeout in seconds before an abandoned object can be
124     * removed</p>
125     *
126     * <p>Setting this property has no effect if
127     * {@link #getRemoveAbandonedOnBorrow() removeAbandonedOnBorrow} and
128     * {@link #getRemoveAbandonedOnMaintenance() removeAbandonedOnMaintenance}
129     * are both false.</p>
130     *
131     * @param removeAbandonedTimeout new abandoned timeout in seconds
132     * @see #getRemoveAbandonedTimeout()
133     */
134    public void setRemoveAbandonedTimeout(final int removeAbandonedTimeout) {
135        this.removeAbandonedTimeout = removeAbandonedTimeout;
136    }
137
138    /**
139     * Determines whether or not to log stack traces for application code
140     * which abandoned an object.
141     */
142    private boolean logAbandoned = false;
143
144    /**
145     * Flag to log stack traces for application code which abandoned
146     * an object.
147     *
148     * Defaults to false.
149     * Logging of abandoned objects adds overhead for every object created
150     * because a stack trace has to be generated.
151     *
152     * @return boolean true if stack trace logging is turned on for abandoned
153     * objects
154     *
155     */
156    public boolean getLogAbandoned() {
157        return this.logAbandoned;
158    }
159
160    /**
161     * Sets the flag to log stack traces for application code which abandoned
162     * an object.
163     *
164     * @param logAbandoned true turns on abandoned stack trace logging
165     * @see #getLogAbandoned()
166     *
167     */
168    public void setLogAbandoned(final boolean logAbandoned) {
169        this.logAbandoned = logAbandoned;
170    }
171
172    /**
173     * Determines whether or not to log full stack traces when logAbandoned is true.
174     * If disabled, then a faster method for logging stack traces with only class data
175     * may be used if possible.
176     *
177     * @since 2.5
178     */
179    private boolean requireFullStackTrace = true;
180
181    /**
182     * Indicates if full stack traces are required when {@link #getLogAbandoned() logAbandoned}
183     * is true. Defaults to true. Logging of abandoned objects requiring a full stack trace will
184     * generate an entire stack trace to generate for every object created. If this is disabled,
185     * a faster but less informative stack walking mechanism may be used if available.
186     *
187     * @return true if full stack traces are required for logging abandoned connections, or false
188     * if abbreviated stack traces are acceptable
189     * @see CallStack
190     * @since 2.5
191     */
192    public boolean getRequireFullStackTrace() {
193        return requireFullStackTrace;
194    }
195
196    /**
197     * Sets the flag to require full stack traces for logging abandoned connections when enabled.
198     *
199     * @param requireFullStackTrace indicates whether or not full stack traces are required in
200     *                              abandoned connection logs
201     * @see CallStack
202     * @see #getRequireFullStackTrace()
203     * @since 2.5
204     */
205    public void setRequireFullStackTrace(final boolean requireFullStackTrace) {
206        this.requireFullStackTrace = requireFullStackTrace;
207    }
208
209    /**
210     * PrintWriter to use to log information on abandoned objects.
211     * Use of default system encoding is deliberate.
212     */
213    private PrintWriter logWriter = new PrintWriter(System.out);
214
215    /**
216     * Returns the log writer being used by this configuration to log
217     * information on abandoned objects. If not set, a PrintWriter based on
218     * System.out with the system default encoding is used.
219     *
220     * @return log writer in use
221     */
222    public PrintWriter getLogWriter() {
223        return logWriter;
224    }
225
226    /**
227     * Sets the log writer to be used by this configuration to log
228     * information on abandoned objects.
229     *
230     * @param logWriter The new log writer
231     */
232    public void setLogWriter(final PrintWriter logWriter) {
233        this.logWriter = logWriter;
234    }
235
236    /**
237     * If the pool implements {@link UsageTracking}, should the pool record a
238     * stack trace every time a method is called on a pooled object and retain
239     * the most recent stack trace to aid debugging of abandoned objects?
240     */
241    private boolean useUsageTracking = false;
242
243    /**
244     * If the pool implements {@link UsageTracking}, should the pool record a
245     * stack trace every time a method is called on a pooled object and retain
246     * the most recent stack trace to aid debugging of abandoned objects?
247     *
248     * @return <code>true</code> if usage tracking is enabled
249     */
250    public boolean getUseUsageTracking() {
251        return useUsageTracking;
252    }
253
254    /**
255     * If the pool implements {@link UsageTracking}, configure whether the pool
256     * should record a stack trace every time a method is called on a pooled
257     * object and retain the most recent stack trace to aid debugging of
258     * abandoned objects.
259     *
260     * @param   useUsageTracking    A value of <code>true</code> will enable
261     *                              the recording of a stack trace on every use
262     *                              of a pooled object
263     */
264    public void setUseUsageTracking(final boolean useUsageTracking) {
265        this.useUsageTracking = useUsageTracking;
266    }
267
268    /**
269     * @since 2.4.3
270     */
271    @Override
272    public String toString() {
273        final StringBuilder builder = new StringBuilder();
274        builder.append("AbandonedConfig [removeAbandonedOnBorrow=");
275        builder.append(removeAbandonedOnBorrow);
276        builder.append(", removeAbandonedOnMaintenance=");
277        builder.append(removeAbandonedOnMaintenance);
278        builder.append(", removeAbandonedTimeout=");
279        builder.append(removeAbandonedTimeout);
280        builder.append(", logAbandoned=");
281        builder.append(logAbandoned);
282        builder.append(", logWriter=");
283        builder.append(logWriter);
284        builder.append(", useUsageTracking=");
285        builder.append(useUsageTracking);
286        builder.append("]");
287        return builder.toString();
288    }
289}