/* * Copyright (c) 2015-2016, Christoph Engelbert (aka noctarius) and * contributors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.noctarius.tengi.spi.pooling; import com.noctarius.tengi.spi.pooling.impl.NonBlockingObjectPool; import java.util.function.Consumer; /** * The <tt>ObjectPool</tt> interface describes the actual object pool implementation * itself. It is used to pre-allocate costly or slow creation processes. The object * that is pooled needs to be reusable however it is guaranteed to only be used by * one acquirer at a given time. After acquisition, if the object is thread-safe, * it might be passed to multiple threads and the thread releasing the object must * not be the acquisition thread. * * @param <T> the type of the pooled object */ public interface ObjectPool<T> { /** * <p>Acquires a pooled object instance. The returns pooled instance might be tested * using a configured {@link com.noctarius.tengi.spi.pooling.ObjectValidator} and * activated using a configured {@link com.noctarius.tengi.spi.pooling.ObjectHandler} * before being returned.</p> * <p>The object that is returned is guaranteed to be valid at the time of testing * however, if based on network connection or other unreliable system, it still might * become invalid at any given point after acquisition.</p> * * @return the pooled element wrapped into a <tt>PooledObject</tt> instance */ default PooledObject<T> acquire() { return acquire(null); } /** * <p>Acquires a pooled object instance. The returns pooled instance might be tested * using a configured {@link com.noctarius.tengi.spi.pooling.ObjectValidator} and * activated using a configured * {@link com.noctarius.tengi.spi.pooling.ObjectHandler#activateObject(Object)} * before being returned. In addition the given <tt>activator</tt> will be called and * can contain additional runtime based logic.</p> * <p>The passed in <tt>activator</tt> is always called before the configured * {@link com.noctarius.tengi.spi.pooling.ObjectHandler#activateObject(Object)} * method.</p> * <p>The object that is returned is guaranteed to be valid at the time of testing * however, if based on network connection or other unreliable system, it still might * become invalid at any given point after acquisition.</p> * * @param activator the runtime activator to execute against the object * @return the pooled element wrapped into a <tt>PooledObject</tt> instance */ PooledObject<T> acquire(Consumer<T> activator); /** * <p>Releases a <tt>PooledObject</tt> to the pool. The returned object instance might be * tested using a configured {@link com.noctarius.tengi.spi.pooling.ObjectValidator} but * it might also be delayed to the next acquisition phase. However the object is passivated * by calling {@link com.noctarius.tengi.spi.pooling.ObjectHandler#passivateObject(Object)} * before returning it to the available pool again.</p> * * @param object the pooled object to release */ default void release(PooledObject<T> object) { release(object, null); } /** * <p>Releases a <tt>PooledObject</tt> to the pool. The returned object instance might be * tested using a configured {@link com.noctarius.tengi.spi.pooling.ObjectValidator} but * it might also be delayed to the next acquisition phase. However the object is passivated * by calling {@link com.noctarius.tengi.spi.pooling.ObjectHandler#passivateObject(Object)} * before returning it to the available pool again. In addition the given <tt>passivator</tt> * will also be called and can contain additional runtime based logic.</p> * <p>The passed in <tt>passivator</tt> is always called before the configured * {@link com.noctarius.tengi.spi.pooling.ObjectHandler#passivateObject(Object)} * method.</p> * * @param object the pooled object to release * @param passivator the runtime passivator to execute against the object */ void release(PooledObject<T> object, Consumer<T> passivator); /** * Closes the pool and destroys all pre-allocated object instances. It will also call the * {@link com.noctarius.tengi.spi.pooling.ObjectHandler#destroy(Object)} method with * each of the objects to free any externally acquired or allocated resources assigned to * the object instance. */ void close(); /** * Creates a new instance of a non-blocking <tt>ObjectPool</tt> using the given parameters. * The returned instance is fully thread-safe and can also create more elements than the * given size however the internal size is never growing and over-capacity elements are only * temporary and will be destroyed immediately when released. * * @param handler the <tt>ObjectHandler</tt> instance to bind * @param size the internal capacity (not maximum capacity) * @param <T> the type of the pooled object * @return the new <tt>ObjectPool</tt> instance */ public static <T> ObjectPool<T> create(ObjectHandler<T> handler, int size) { return create(handler, null, size); } /** * Creates a new instance of a non-blocking <tt>ObjectPool</tt> using the given parameters. * The returned instance is fully thread-safe and can also create more elements than the * given size however the internal size is never growing and over-capacity elements are only * temporary and will be destroyed immediately when released. * * @param handler the <tt>ObjectHandler</tt> instance to bind * @param validator the <tt>ObjectValidator</tt> instance to bind * @param size the internal capacity (not maximum capacity) * @param <T> the type of the pooled object * @return the new <tt>ObjectPool</tt> instance */ public static <T> ObjectPool<T> create(ObjectHandler<T> handler, ObjectValidator<T> validator, int size) { return new NonBlockingObjectPool<T>(handler, validator, size); } }