    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 *      https://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;
    018
    019import java.io.PrintWriter;
    020import java.time.Duration;
    021import java.time.Instant;
    022import java.util.Deque;
    023
    024/**
    025 * Defines the wrapper that is used to track the additional information, such as
    026 * state, for the pooled objects.
    027 * <p>
    028 * Implementations of this class are required to be thread-safe.
    029 * </p>
    030 *
    031 * @param <T> the type of object in the pool.
    032 * @since 2.0
    033 */
    034public interface PooledObject<T> extends Comparable<PooledObject<T>> {
    035
    036    /**
    037     * Gets the wrapped object or null.
    038     *
    039     * @param <T> the type of object in the pool.
    040     * @param pooledObject the PooledObject to unwrap, may be null.
    041     * @return the wrapped object or null.
    042     * @since 2.13.0
    043     */
    044    static <T> T getObject(final PooledObject<T> pooledObject) {
    045        return pooledObject != null ? pooledObject.getObject() : null;
    046    }
    047
    048    /**
    049     * Tests whether the given PooledObject is null <em>or</em> wraps a null.
    050     *
    051     * @param pooledObject the PooledObject to test, may be null.
    052     * @return whether the given PooledObject is null <em>or</em> wraps a null.
    053     * @since 2.12.0
    054     */
    055    static boolean isNull(final PooledObject<?> pooledObject) {
    056        return getObject(pooledObject) == null;
    057    }
    058
    059    /**
    060     * Tests whether the given PooledObject isn't null <em>and</em> doesn't wraps a null.
    061     *
    062     * @param pooledObject the PooledObject to test, may be null.
    063     * @return whether the given PooledObject isn't null <em>and</em> doesn't wraps a null.
    064     * @since 2.13.0
    065     */
    066    static boolean nonNull(final PooledObject<?> pooledObject) {
    067        return getObject(pooledObject) != null;
    068    }
    069
    070    /**
    071     * Allocates the object.
    072     *
    073     * @return {@code true} if the original state was {@link PooledObjectState#IDLE IDLE}
    074     */
    075    boolean allocate();
    076
    077    /**
    078     * Orders instances based on idle time - i.e. the length of time since the
    079     * instance was returned to the pool. Used by the GKOP idle object evictor.
    080     * <p>
    081     * Note: This class has a natural ordering that is inconsistent with
    082     *       equals if distinct objects have the same identity hash code.
    083     * </p>
    084     * <p>
    085     * {@inheritDoc}
    086     * </p>
    087     */
    088    @Override
    089    int compareTo(PooledObject<T> other);
    090
    091    /**
    092     * Deallocates the object and sets it {@link PooledObjectState#IDLE IDLE}
    093     * if it is currently {@link PooledObjectState#ALLOCATED ALLOCATED}.
    094     *
    095     * @return {@code true} if the state was {@link PooledObjectState#ALLOCATED ALLOCATED}.
    096     */
    097    boolean deallocate();
    098
    099    /**
    100     * Notifies the object that the eviction test has ended.
    101     *
    102     * @param idleQueue The queue of idle objects to which the object should be
    103     *                  returned.
    104     * @return  Currently not used.
    105     */
    106    boolean endEvictionTest(Deque<PooledObject<T>> idleQueue);
    107
    108    @Override
    109    boolean equals(Object obj);
    110
    111    /**
    112     * Gets the amount of time this object last spent in the active state (it may still be active in which case
    113     * subsequent calls will return an increased value).
    114     *
    115     * @return The duration last spent in the active state.
    116     * @since 2.11.0
    117     */
    118    default Duration getActiveDuration() {
    119        // Take copies to avoid threading issues
    120        final Instant lastReturnInstant = getLastReturnInstant();
    121        final Instant lastBorrowInstant = getLastBorrowInstant();
    122        // @formatter:off
    123        return lastReturnInstant.isAfter(lastBorrowInstant) ?
    124                Duration.between(lastBorrowInstant, lastReturnInstant) :
    125                Duration.between(lastBorrowInstant, Instant.now());
    126        // @formatter:on
    127    }
    128
    129    /**
    130     * Gets the amount of time this object last spent in the active state (it may still be active in which case
    131     * subsequent calls will return an increased value).
    132     *
    133     * @return The duration last spent in the active state.
    134     * @since 2.10.0
    135     * @deprecated Use {@link #getActiveDuration()}.
    136     */
    137    @Deprecated
    138    default Duration getActiveTime() {
    139        return getActiveDuration();
    140    }
    141
    142    /**
    143     * Gets the amount of time in milliseconds this object last spent in the
    144     * active state (it may still be active in which case subsequent calls will
    145     * return an increased value).
    146     *
    147     * @return The time in milliseconds last spent in the active state.
    148     * @deprecated Use {@link #getActiveTime()} which offers the best precision.
    149     */
    150    @Deprecated
    151    long getActiveTimeMillis();
    152
    153    /**
    154     * Gets the number of times this object has been borrowed.
    155     *
    156     * @return -1 by default for implementations prior to release 2.7.0.
    157     * @since 2.7.0
    158     */
    159    default long getBorrowedCount() {
    160        return -1;
    161    }
    162
    163    /**
    164     * Gets the time (using the same basis as {@link Instant#now()}) that this object was created.
    165     *
    166     * @return The creation time for the wrapped object.
    167     * @since 2.11.0
    168     */
    169    default Instant getCreateInstant() {
    170        return Instant.ofEpochMilli(getCreateTime());
    171    }
    172
    173    /**
    174     * Gets the time (using the same basis as
    175     * {@link java.time.Clock#instant()}) that this object was created.
    176     *
    177     * @return The creation time for the wrapped object.
    178     * @deprecated Use {@link #getCreateInstant()} which offers the best precision.
    179     */
    180    @Deprecated
    181    long getCreateTime();
    182
    183    /**
    184     * Gets the duration since this object was created (using {@link Instant#now()}).
    185     *
    186     * @return The duration since this object was created.
    187     * @since 2.12.0
    188     */
    189    default Duration getFullDuration() {
    190        return Duration.between(getCreateInstant(), Instant.now());
    191    }
    192
    193    /**
    194     * Gets the amount of time that this object last spend in the
    195     * idle state (it may still be idle in which case subsequent calls will
    196     * return an increased value).
    197     *
    198     * @return The amount of time in last spent in the idle state.
    199     * @since 2.11.0
    200     */
    201    default Duration getIdleDuration() {
    202        return Duration.ofMillis(getIdleTimeMillis());
    203    }
    204
    205    /**
    206     * Gets the amount of time that this object last spend in the
    207     * idle state (it may still be idle in which case subsequent calls will
    208     * return an increased value).
    209     *
    210     * @return The amount of time in last spent in the idle state.
    211     * @since 2.10.0
    212     * @deprecated Use {@link #getIdleDuration()}.
    213     */
    214    @Deprecated
    215    default Duration getIdleTime() {
    216        return Duration.ofMillis(getIdleTimeMillis());
    217    }
    218
    219    /**
    220     * Gets the amount of time in milliseconds that this object last spend in the
    221     * idle state (it may still be idle in which case subsequent calls will
    222     * return an increased value).
    223     *
    224     * @return The time in milliseconds last spent in the idle state.
    225     * @deprecated Use {@link #getIdleTime()} which offers the best precision.
    226     */
    227    @Deprecated
    228    long getIdleTimeMillis();
    229
    230    /**
    231     * Gets the time the wrapped object was last borrowed.
    232     *
    233     * @return The time the object was last borrowed.
    234     * @since 2.11.0
    235     */
    236    default Instant getLastBorrowInstant() {
    237        return Instant.ofEpochMilli(getLastBorrowTime());
    238    }
    239
    240    /**
    241     * Gets the time the wrapped object was last borrowed.
    242     *
    243     * @return The time the object was last borrowed.
    244     * @deprecated Use {@link #getLastBorrowInstant()} which offers the best precision.
    245     */
    246    @Deprecated
    247    long getLastBorrowTime();
    248
    249    /**
    250     * Gets the time the wrapped object was last borrowed.
    251     *
    252     * @return The time the object was last borrowed.
    253     * @since 2.11.0
    254     */
    255    default Instant getLastReturnInstant() {
    256        return Instant.ofEpochMilli(getLastReturnTime());
    257    }
    258
    259    /**
    260     * Gets the time the wrapped object was last returned.
    261     *
    262     * @return The time the object was last returned.
    263     * @deprecated Use {@link #getLastReturnInstant()} which offers the best precision.
    264     */
    265    @Deprecated
    266    long getLastReturnTime();
    267
    268    /**
    269     * Gets an estimate of the last time this object was used. If the class of the pooled object implements
    270     * {@link TrackedUse}, what is returned is the maximum of {@link TrackedUse#getLastUsedInstant()} and
    271     * {@link #getLastBorrowTime()}; otherwise this method gives the same value as {@link #getLastBorrowTime()}.
    272     *
    273     * @return the last time this object was used
    274     * @since 2.11.0
    275     */
    276    default Instant getLastUsedInstant() {
    277        return Instant.ofEpochMilli(getLastUsedTime());
    278    }
    279
    280    /**
    281     * Gets an estimate of the last time this object was used.  If the class
    282     * of the pooled object implements {@link TrackedUse}, what is returned is
    283     * the maximum of {@link TrackedUse#getLastUsedInstant()} and
    284     * {@link #getLastBorrowTime()}; otherwise this method gives the same
    285     * value as {@link #getLastBorrowTime()}.
    286     *
    287     * @return the last time this object was used.
    288     * @deprecated Use {@link #getLastUsedInstant()} which offers the best precision.
    289     */
    290    @Deprecated
    291    long getLastUsedTime();
    292
    293    /**
    294     * Gets the underlying object that is wrapped by this instance of
    295     * {@link PooledObject}.
    296     *
    297     * @return The wrapped object.
    298     */
    299    T getObject();
    300
    301    /**
    302     * Gets the state of this object.
    303     *
    304     * @return state
    305     */
    306    PooledObjectState getState();
    307
    308    @Override
    309    int hashCode();
    310
    311    /**
    312     * Sets the state to {@link PooledObjectState#INVALID INVALID}.
    313     */
    314    void invalidate();
    315
    316    /**
    317     * Marks the pooled object as abandoned.
    318     */
    319    void markAbandoned();
    320
    321    /**
    322     * Marks the object as returning to the pool.
    323     */
    324    void markReturning();
    325
    326    /**
    327     * Prints the stack trace of the code that borrowed this pooled object and
    328     * the stack trace of the last code to use this object (if available) to
    329     * the supplied writer.
    330     *
    331     * @param   writer  The destination for the debug output.
    332     */
    333    void printStackTrace(PrintWriter writer);
    334
    335    /**
    336     * Sets whether to use abandoned object tracking. If this is true the
    337     * implementation will need to record the stack trace of the last caller to
    338     * borrow this object.
    339     *
    340     * @param   logAbandoned    The new configuration setting for abandoned
    341     *                          object tracking.
    342     */
    343    void setLogAbandoned(boolean logAbandoned);
    344
    345    /**
    346     * Sets the stack trace generation strategy based on whether or not fully detailed stack traces are required.
    347     * When set to false, abandoned logs may only include caller class information rather than method names, line
    348     * numbers, and other normal metadata available in a full stack trace.
    349     *
    350     * @param requireFullStackTrace the new configuration setting for abandoned object logging.
    351     * @since 2.7.0
    352     */
    353    default void setRequireFullStackTrace(final boolean requireFullStackTrace) {
    354        // noop
    355    }
    356
    357    /**
    358     * Attempts to place the pooled object in the
    359     * {@link PooledObjectState#EVICTION} state.
    360     *
    361     * @return {@code true} if the object was placed in the
    362     *         {@link PooledObjectState#EVICTION} state otherwise
    363     *         {@code false}.
    364     */
    365    boolean startEvictionTest();
    366
    367    /**
    368     * Gets a String form of the wrapper for debug purposes. The format is
    369     * not fixed and may change at any time.
    370     *
    371     * {@inheritDoc}
    372     */
    373    @Override
    374    String toString();
    375
    376    /**
    377     * Records the current stack trace as the last time the object was used.
    378     */
    379    void use();
    380
    381}