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