All Downloads are FREE. Search and download functionalities are using the official Maven repository.

reactor.pool.Pool Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-Present Pivotal Software Inc, 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
 *
 *       https://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 reactor.pool;

import java.time.Duration;
import java.util.function.Function;

import org.reactivestreams.Publisher;

import reactor.core.Disposable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * A reactive pool of objects.
 * @author Simon Baslé
 */
public interface Pool extends Disposable {

    /**
     * Warms up the {@link Pool}, if needed. This typically instructs the pool to check for a minimum size and allocate
     * necessary objects when the minimum is not reached. The resulting {@link Mono} emits the number of extra resources
     * it created as a result of the {@link PoolBuilder#sizeBetween(int, int) allocation minimum}.
     * 

* Note that no work nor allocation is performed until the {@link Mono} is subscribed to. *

* Implementations MAY include more behavior, but there is no restriction on the way this method is called by users * (it should be possible to call it at any time, as many times as needed or not at all). * * @apiNote this API is intended to easily reach the minimum allocated size (see {@link PoolBuilder#sizeBetween(int, int)}) * without paying that cost on the first {@link #acquire()}. However, implementors should also consider creating * the extra resources needed to honor that minimum during the acquire, as one cannot rely on the user calling * warmup() consistently. * * @return a cold {@link Mono} that triggers resource warmup and emits the number of warmed up resources */ Mono warmup(); /** * Manually acquire a {@code POOLABLE} from the pool upon subscription and become responsible for its release. * The object is wrapped in a {@link PooledRef} which can be used for manually releasing the object back to the pool * or invalidating it. As a result, you MUST maintain a reference to it throughout the code that makes use of the * underlying resource. *

* This is typically the case when one needs to wrap the actual resource into a decorator version, where the reference * to the {@link PooledRef} can be stored. On the other hand, if the resource and its usage directly expose reactive * APIs, you might want to prefer to use {@link #withPoolable(Function)}. *

* The resulting {@link Mono} emits the {@link PooledRef} as the {@code POOLABLE} becomes available. Cancelling the * {@link org.reactivestreams.Subscription} before the {@code POOLABLE} has been emitted will either avoid object * acquisition entirely or will translate to a {@link PooledRef#release() release} of the {@code POOLABLE}. * Once the resource is emitted though, it is the responsibility of the caller to release the poolable object via * the {@link PooledRef} {@link PooledRef#release() release methods} when the resource is not used anymore * (directly OR indirectly, eg. the results from multiple statements derived from a DB connection type of resource * have all been processed). * * @return a {@link Mono}, each subscription to which represents an individual act of acquiring a pooled object and * manually managing its lifecycle from there on * @see #withPoolable(Function) */ Mono> acquire(); /** * Manually acquire a {@code POOLABLE} from the pool upon subscription and become responsible for its release. * The provided {@link Duration} acts as a timeout that only applies if the acquisition is added to the pending * queue, i.e. there is no idle resource and no new resource can be created currently, so one needs to wait * for a release before a resource can be delivered. For a timeout that covers both this pending case and the * time it would take to allocate a new resource, simply apply the {@link Mono#timeout(Duration)} operator to * the returned Mono. For a timeout that only applies to resource allocation, build the pool with the standard * {@link Mono#timeout(Duration)} operator chained to the {@link PoolBuilder#from(Publisher) allocator}. *

* The object is wrapped in a {@link PooledRef} which can be used for manually releasing the object back to the pool * or invalidating it. As a result, you MUST maintain a reference to it throughout the code that makes use of the * underlying resource. *

* This is typically the case when one needs to wrap the actual resource into a decorator version, where the reference * to the {@link PooledRef} can be stored. On the other hand, if the resource and its usage directly expose reactive * APIs, you might want to prefer to use {@link #withPoolable(Function)}. *

* The resulting {@link Mono} emits the {@link PooledRef} as the {@code POOLABLE} becomes available. Cancelling the * {@link org.reactivestreams.Subscription} before the {@code POOLABLE} has been emitted will either avoid object * acquisition entirely or will translate to a {@link PooledRef#release() release} of the {@code POOLABLE}. * Once the resource is emitted though, it is the responsibility of the caller to release the poolable object via * the {@link PooledRef} {@link PooledRef#release() release methods} when the resource is not used anymore * (directly OR indirectly, eg. the results from multiple statements derived from a DB connection type of resource * have all been processed). * * @return a {@link Mono}, each subscription to which represents an individual act of acquiring a pooled object and * manually managing its lifecycle from there on * @see #withPoolable(Function) */ Mono> acquire(Duration timeout); /** * Acquire a {@code POOLABLE} object from the pool upon subscription and declaratively use it, automatically releasing * the object back to the pool once the derived usage pipeline terminates or is cancelled. This acquire-use-and-release * scope is represented by a user provided {@link Function}. *

* This is typically useful when the resource (and its usage patterns) directly involve reactive APIs that can be * composed within the {@link Function} scope. *

* The {@link Mono} provided to the {@link Function} emits the {@code POOLABLE} as it becomes available. Cancelling * the {@link org.reactivestreams.Subscription} before the {@code POOLABLE} has been emitted will either avoid object * acquisition entirely or will translate to a {@link PooledRef#release() release} of the {@code POOLABLE}. * * @param scopeFunction the {@link Function} to apply to the {@link Mono} delivering the POOLABLE to instantiate and * trigger a processing pipeline around it. * @return a {@link Flux}, each subscription to which represents an individual act of acquiring a pooled object, * processing it as declared in {@code scopeFunction} and automatically releasing it. * @see #acquire() */ default Flux withPoolable(Function> scopeFunction) { return Flux.usingWhen(acquire(), slot -> { POOLABLE poolable = slot.poolable(); if (poolable == null) return Mono.empty(); return scopeFunction.apply(poolable); }, PooledRef::release, PooledRef::release); } /** * Shutdown the pool by: *

    *
  • * notifying every acquire still pending that the pool has been shut down, * via a {@link RuntimeException} *
  • *
  • * releasing each pooled resource, according to the release handler defined in * the {@link PoolBuilder} *
  • *
* This imperative style method returns once every release handler has been started in * step 2, but doesn't necessarily block until full completion of said releases. * For a blocking alternative, use {@link #disposeLater()} and {@link Mono#block()}. *

* By default this is implemented as {@code .disposeLater().subscribe()}. As a result * failures during release could be swallowed. */ @Override default void dispose() { disposeLater().subscribe(); } /** * Returns a {@link Mono} that represents a lazy asynchronous shutdown of this {@link Pool}. * Shutdown doesn't happen until the {@link Mono} is {@link Mono#subscribe() subscribed}. * Otherwise, it performs the same steps as in the imperative counterpart, {@link #dispose()}. *

* If the pool has been already shut down, returns {@link Mono#empty()}. Completion of * the {@link Mono} indicates completion of the shutdown process. * * @return a Mono triggering the shutdown of the pool once subscribed. */ Mono disposeLater(); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy