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 * https://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;
18
19 import java.io.PrintWriter;
20 import java.time.Duration;
21 import java.time.Instant;
22 import java.util.Deque;
23
24 /**
25 * Defines the wrapper that is used to track the additional information, such as
26 * state, for the pooled objects.
27 * <p>
28 * Implementations of this class are required to be thread-safe.
29 * </p>
30 *
31 * @param <T> the type of object in the pool.
32 * @since 2.0
33 */
34 public interface PooledObject<T> extends Comparable<PooledObject<T>> {
35
36 /**
37 * Gets the wrapped object or null.
38 *
39 * @param <T> the type of object in the pool.
40 * @param pooledObject the PooledObject to unwrap, may be null.
41 * @return the wrapped object or null.
42 * @since 2.13.0
43 */
44 static <T> T getObject(final PooledObject<T> pooledObject) {
45 return pooledObject != null ? pooledObject.getObject() : null;
46 }
47
48 /**
49 * Tests whether the given PooledObject is null <em>or</em> wraps a null.
50 *
51 * @param pooledObject the PooledObject to test, may be null.
52 * @return whether the given PooledObject is null <em>or</em> wraps a null.
53 * @since 2.12.0
54 */
55 static boolean isNull(final PooledObject<?> pooledObject) {
56 return getObject(pooledObject) == null;
57 }
58
59 /**
60 * Tests whether the given PooledObject isn't null <em>and</em> doesn't wraps a null.
61 *
62 * @param pooledObject the PooledObject to test, may be null.
63 * @return whether the given PooledObject isn't null <em>and</em> doesn't wraps a null.
64 * @since 2.13.0
65 */
66 static boolean nonNull(final PooledObject<?> pooledObject) {
67 return getObject(pooledObject) != null;
68 }
69
70 /**
71 * Allocates the object.
72 *
73 * @return {@code true} if the original state was {@link PooledObjectState#IDLE IDLE}
74 */
75 boolean allocate();
76
77 /**
78 * Orders instances based on idle time - i.e. the length of time since the
79 * instance was returned to the pool. Used by the GKOP idle object evictor.
80 * <p>
81 * Note: This class has a natural ordering that is inconsistent with
82 * equals if distinct objects have the same identity hash code.
83 * </p>
84 * <p>
85 * {@inheritDoc}
86 * </p>
87 */
88 @Override
89 int compareTo(PooledObject<T> other);
90
91 /**
92 * Deallocates the object and sets it {@link PooledObjectState#IDLE IDLE}
93 * if it is currently {@link PooledObjectState#ALLOCATED ALLOCATED}.
94 *
95 * @return {@code true} if the state was {@link PooledObjectState#ALLOCATED ALLOCATED}.
96 */
97 boolean deallocate();
98
99 /**
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 }