AbandonedConfig.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.pool2.impl;

  18. import java.io.OutputStreamWriter;
  19. import java.io.PrintWriter;
  20. import java.nio.charset.Charset;
  21. import java.time.Duration;

  22. import org.apache.commons.pool2.TrackedUse;
  23. import org.apache.commons.pool2.UsageTracking;

  24. /**
  25.  * Configuration settings for abandoned object removal.
  26.  *
  27.  * @since 2.0
  28.  */
  29. public class AbandonedConfig {

  30.     /**
  31.      * The 5 minutes Duration.
  32.      */
  33.     private static final Duration DEFAULT_REMOVE_ABANDONED_TIMEOUT_DURATION = Duration.ofMinutes(5);

  34.     /**
  35.      * Creates a new instance with values from the given instance.
  36.      *
  37.      * @param abandonedConfig the source, may be null.
  38.      * @return A new instance or null if the input is null.
  39.      * @since 2.11.0
  40.      */
  41.     public static AbandonedConfig copy(final AbandonedConfig abandonedConfig) {
  42.         return abandonedConfig == null ? null : new AbandonedConfig(abandonedConfig);
  43.     }

  44.     /**
  45.      * Whether or not borrowObject performs abandoned object removal.
  46.      */
  47.     private boolean removeAbandonedOnBorrow;

  48.     /**
  49.      * Whether or not pool maintenance (evictor) performs abandoned object
  50.      * removal.
  51.      */
  52.     private boolean removeAbandonedOnMaintenance;

  53.     /**
  54.      * Timeout before an abandoned object can be removed.
  55.      */
  56.     private Duration removeAbandonedTimeoutDuration = DEFAULT_REMOVE_ABANDONED_TIMEOUT_DURATION;

  57.     /**
  58.      * Determines whether or not to log stack traces for application code
  59.      * which abandoned an object.
  60.      */
  61.     private boolean logAbandoned;

  62.     /**
  63.      * Determines whether or not to log full stack traces when logAbandoned is true.
  64.      * If disabled, then a faster method for logging stack traces with only class data
  65.      * may be used if possible.
  66.      *
  67.      * @since 2.5
  68.      */
  69.     private boolean requireFullStackTrace = true;

  70.     /**
  71.      * PrintWriter to use to log information on abandoned objects.
  72.      * Use of default system encoding is deliberate.
  73.      */
  74.     private PrintWriter logWriter = new PrintWriter(new OutputStreamWriter(System.out, Charset.defaultCharset()));

  75.     /**
  76.      * If the pool implements {@link UsageTracking}, should the pool record a
  77.      * stack trace every time a method is called on a pooled object and retain
  78.      * the most recent stack trace to aid debugging of abandoned objects?
  79.      */
  80.     private boolean useUsageTracking;

  81.     /**
  82.      * Creates a new instance.
  83.      */
  84.     public AbandonedConfig() {
  85.         // empty
  86.     }

  87.     /**
  88.      * Creates a new instance with values from the given instance.
  89.      *
  90.      * @param abandonedConfig the source.
  91.      */
  92.     @SuppressWarnings("resource")
  93.     private AbandonedConfig(final AbandonedConfig abandonedConfig) {
  94.         this.setLogAbandoned(abandonedConfig.getLogAbandoned());
  95.         this.setLogWriter(abandonedConfig.getLogWriter());
  96.         this.setRemoveAbandonedOnBorrow(abandonedConfig.getRemoveAbandonedOnBorrow());
  97.         this.setRemoveAbandonedOnMaintenance(abandonedConfig.getRemoveAbandonedOnMaintenance());
  98.         this.setRemoveAbandonedTimeout(abandonedConfig.getRemoveAbandonedTimeoutDuration());
  99.         this.setUseUsageTracking(abandonedConfig.getUseUsageTracking());
  100.         this.setRequireFullStackTrace(abandonedConfig.getRequireFullStackTrace());
  101.     }

  102.     /**
  103.      * Flag to log stack traces for application code which abandoned
  104.      * an object.
  105.      *
  106.      * Defaults to false.
  107.      * Logging of abandoned objects adds overhead for every object created
  108.      * because a stack trace has to be generated.
  109.      *
  110.      * @return boolean true if stack trace logging is turned on for abandoned
  111.      * objects
  112.      */
  113.     public boolean getLogAbandoned() {
  114.         return this.logAbandoned;
  115.     }

  116.     /**
  117.      * Gets the log writer being used by this configuration to log
  118.      * information on abandoned objects. If not set, a PrintWriter based on
  119.      * System.out with the system default encoding is used.
  120.      *
  121.      * @return log writer in use
  122.      */
  123.     public PrintWriter getLogWriter() {
  124.         return logWriter;
  125.     }

  126.     /**
  127.      * <p>Flag to remove abandoned objects if they exceed the
  128.      * removeAbandonedTimeout when borrowObject is invoked.</p>
  129.      *
  130.      * <p>The default value is false.</p>
  131.      *
  132.      * <p>If set to true, abandoned objects are removed by borrowObject if
  133.      * there are fewer than 2 idle objects available in the pool and
  134.      * {@code getNumActive() &gt; getMaxTotal() - 3}</p>
  135.      *
  136.      * @return true if abandoned objects are to be removed by borrowObject
  137.      */
  138.     public boolean getRemoveAbandonedOnBorrow() {
  139.         return this.removeAbandonedOnBorrow;
  140.     }

  141.     /**
  142.      * <p>Flag to remove abandoned objects if they exceed the
  143.      * removeAbandonedTimeout when pool maintenance (the "evictor")
  144.      * runs.</p>
  145.      *
  146.      * <p>The default value is false.</p>
  147.      *
  148.      * <p>If set to true, abandoned objects are removed by the pool
  149.      * maintenance thread when it runs.  This setting has no effect
  150.      * unless maintenance is enabled by setting
  151.      * {@link GenericObjectPool#getDurationBetweenEvictionRuns()}
  152.      * to a positive number.</p>
  153.      *
  154.      * @return true if abandoned objects are to be removed by the evictor
  155.      */
  156.     public boolean getRemoveAbandonedOnMaintenance() {
  157.         return this.removeAbandonedOnMaintenance;
  158.     }

  159.     /**
  160.      * <p>Timeout in seconds before an abandoned object can be removed.</p>
  161.      *
  162.      * <p>The time of most recent use of an object is the maximum (latest) of
  163.      * {@link TrackedUse#getLastUsedInstant()} (if this class of the object implements
  164.      * TrackedUse) and the time when the object was borrowed from the pool.</p>
  165.      *
  166.      * <p>The default value is 300 seconds.</p>
  167.      *
  168.      * @return the abandoned object timeout in seconds.
  169.      * @deprecated Use {@link #getRemoveAbandonedTimeoutDuration()}.
  170.      */
  171.     @Deprecated
  172.     public int getRemoveAbandonedTimeout() {
  173.         return (int) this.removeAbandonedTimeoutDuration.getSeconds();
  174.     }

  175.     /**
  176.      * <p>Timeout before an abandoned object can be removed.</p>
  177.      *
  178.      * <p>The time of most recent use of an object is the maximum (latest) of
  179.      * {@link TrackedUse#getLastUsedInstant()} (if this class of the object implements
  180.      * TrackedUse) and the time when the object was borrowed from the pool.</p>
  181.      *
  182.      * <p>The default value is 300 seconds.</p>
  183.      *
  184.      * @return the abandoned object timeout.
  185.      * @since 2.10.0
  186.      */
  187.     public Duration getRemoveAbandonedTimeoutDuration() {
  188.         return this.removeAbandonedTimeoutDuration;
  189.     }

  190.     /**
  191.      * Indicates if full stack traces are required when {@link #getLogAbandoned() logAbandoned}
  192.      * is true. Defaults to true. Logging of abandoned objects requiring a full stack trace will
  193.      * generate an entire stack trace to generate for every object created. If this is disabled,
  194.      * a faster but less informative stack walking mechanism may be used if available.
  195.      *
  196.      * @return true if full stack traces are required for logging abandoned connections, or false
  197.      * if abbreviated stack traces are acceptable
  198.      * @see CallStack
  199.      * @since 2.5
  200.      */
  201.     public boolean getRequireFullStackTrace() {
  202.         return requireFullStackTrace;
  203.     }

  204.     /**
  205.      * If the pool implements {@link UsageTracking}, should the pool record a
  206.      * stack trace every time a method is called on a pooled object and retain
  207.      * the most recent stack trace to aid debugging of abandoned objects?
  208.      *
  209.      * @return {@code true} if usage tracking is enabled
  210.      */
  211.     public boolean getUseUsageTracking() {
  212.         return useUsageTracking;
  213.     }

  214.     /**
  215.      * Sets the flag to log stack traces for application code which abandoned
  216.      * an object.
  217.      *
  218.      * @param logAbandoned true turns on abandoned stack trace logging
  219.      * @see #getLogAbandoned()
  220.      */
  221.     public void setLogAbandoned(final boolean logAbandoned) {
  222.         this.logAbandoned = logAbandoned;
  223.     }

  224.     /**
  225.      * Sets the log writer to be used by this configuration to log
  226.      * information on abandoned objects.
  227.      *
  228.      * @param logWriter The new log writer
  229.      */
  230.     public void setLogWriter(final PrintWriter logWriter) {
  231.         this.logWriter = logWriter;
  232.     }

  233.     /**
  234.      * Flag to remove abandoned objects if they exceed the
  235.      * removeAbandonedTimeout when borrowObject is invoked.
  236.      *
  237.      * @param removeAbandonedOnBorrow true means abandoned objects will be
  238.      *   removed by borrowObject
  239.      * @see #getRemoveAbandonedOnBorrow()
  240.      */
  241.     public void setRemoveAbandonedOnBorrow(final boolean removeAbandonedOnBorrow) {
  242.         this.removeAbandonedOnBorrow = removeAbandonedOnBorrow;
  243.     }

  244.     /**
  245.      * Flag to remove abandoned objects if they exceed the
  246.      * removeAbandonedTimeout when pool maintenance runs.
  247.      *
  248.      * @param removeAbandonedOnMaintenance true means abandoned objects will be
  249.      *   removed by pool maintenance
  250.      * @see #getRemoveAbandonedOnMaintenance
  251.      */
  252.     public void setRemoveAbandonedOnMaintenance(final boolean removeAbandonedOnMaintenance) {
  253.         this.removeAbandonedOnMaintenance = removeAbandonedOnMaintenance;
  254.     }

  255.     /**
  256.      * Sets the timeout before an abandoned object can be
  257.      * removed.
  258.      *
  259.      * <p>Setting this property has no effect if
  260.      * {@link #getRemoveAbandonedOnBorrow() removeAbandonedOnBorrow} and
  261.      * {@link #getRemoveAbandonedOnMaintenance() removeAbandonedOnMaintenance}
  262.      * are both false.</p>
  263.      *
  264.      * @param removeAbandonedTimeout new abandoned timeout
  265.      * @see #getRemoveAbandonedTimeoutDuration()
  266.      * @since 2.10.0
  267.      */
  268.     public void setRemoveAbandonedTimeout(final Duration removeAbandonedTimeout) {
  269.         this.removeAbandonedTimeoutDuration = PoolImplUtils.nonNull(removeAbandonedTimeout, DEFAULT_REMOVE_ABANDONED_TIMEOUT_DURATION);
  270.     }

  271.     /**
  272.      * Sets the timeout in seconds before an abandoned object can be
  273.      * removed.
  274.      *
  275.      * <p>Setting this property has no effect if
  276.      * {@link #getRemoveAbandonedOnBorrow() removeAbandonedOnBorrow} and
  277.      * {@link #getRemoveAbandonedOnMaintenance() removeAbandonedOnMaintenance}
  278.      * are both false.</p>
  279.      *
  280.      * @param removeAbandonedTimeoutSeconds new abandoned timeout in seconds
  281.      * @see #getRemoveAbandonedTimeoutDuration()
  282.      * @deprecated Use {@link #setRemoveAbandonedTimeout(Duration)}.
  283.      */
  284.     @Deprecated
  285.     public void setRemoveAbandonedTimeout(final int removeAbandonedTimeoutSeconds) {
  286.         setRemoveAbandonedTimeout(Duration.ofSeconds(removeAbandonedTimeoutSeconds));
  287.     }

  288.     /**
  289.      * Sets the flag to require full stack traces for logging abandoned connections when enabled.
  290.      *
  291.      * @param requireFullStackTrace indicates whether or not full stack traces are required in
  292.      *                              abandoned connection logs
  293.      * @see CallStack
  294.      * @see #getRequireFullStackTrace()
  295.      * @since 2.5
  296.      */
  297.     public void setRequireFullStackTrace(final boolean requireFullStackTrace) {
  298.         this.requireFullStackTrace = requireFullStackTrace;
  299.     }

  300.     /**
  301.      * If the pool implements {@link UsageTracking}, configure whether the pool
  302.      * should record a stack trace every time a method is called on a pooled
  303.      * object and retain the most recent stack trace to aid debugging of
  304.      * abandoned objects.
  305.      *
  306.      * @param   useUsageTracking    A value of {@code true} will enable
  307.      *                              the recording of a stack trace on every use
  308.      *                              of a pooled object
  309.      */
  310.     public void setUseUsageTracking(final boolean useUsageTracking) {
  311.         this.useUsageTracking = useUsageTracking;
  312.     }

  313.     /**
  314.      * @since 2.4.3
  315.      */
  316.     @Override
  317.     public String toString() {
  318.         final StringBuilder builder = new StringBuilder();
  319.         builder.append("AbandonedConfig [removeAbandonedOnBorrow=");
  320.         builder.append(removeAbandonedOnBorrow);
  321.         builder.append(", removeAbandonedOnMaintenance=");
  322.         builder.append(removeAbandonedOnMaintenance);
  323.         builder.append(", removeAbandonedTimeoutDuration=");
  324.         builder.append(removeAbandonedTimeoutDuration);
  325.         builder.append(", logAbandoned=");
  326.         builder.append(logAbandoned);
  327.         builder.append(", logWriter=");
  328.         builder.append(logWriter);
  329.         builder.append(", useUsageTracking=");
  330.         builder.append(useUsageTracking);
  331.         builder.append("]");
  332.         return builder.toString();
  333.     }
  334. }