public class SimpleDequePool<POOLABLE> extends Object
SimpleDequePool is based on Deque for idle resources and pending Pool.acquire() Monos,
allowing both to be ordered either LIFO or FIFO.
It uses non-blocking drain loops to deliver resources to borrowers, which means that a resource could
be handed off on any of the following threads:
Pool.acquire() Mono was subscribedPoolBuilder.acquisitionScheduler(Scheduler) property of the builder can be used.InstrumentedPool.PoolMetricsDisposable.Composite, Disposable.Swap| Modifier and Type | Field and Description |
|---|---|
protected static AtomicReferenceFieldUpdater<SimpleDequePool,Deque> |
IDLE_RESOURCES |
| Modifier and Type | Method and Description |
|---|---|
Mono<PooledRef<POOLABLE>> |
acquire()
Manually acquire a
POOLABLE from the pool upon subscription and become responsible for its release. |
Mono<PooledRef<POOLABLE>> |
acquire(Duration timeout)
Manually acquire a
POOLABLE from the pool upon subscription and become responsible for its release. |
int |
acquiredSize()
Measure the current number of resources that have been successfully
acquired and are in active use, outside of the
control of the pool until they're released back to it. |
int |
allocatedSize()
Measure the current number of allocated resources in the
Pool, acquired
or idle. |
PoolConfig<POOLABLE> |
config()
Return the pool's
configuration. |
Mono<Void> |
disposeLater()
|
int |
getMaxAllocatedSize()
Get the maximum number of live resources this
Pool will allow. |
int |
getMaxPendingAcquireSize()
Get the maximum number of
Pool.acquire() this Pool can queue in
a pending state when no available resource is immediately handy (and the Pool
cannot allocate more resources). |
int |
idleSize()
Measure the current number of idle resources in the
Pool. |
boolean |
isDisposed() |
boolean |
isInactiveForMoreThan(Duration duration)
A convenience way to check the pool is inactive, in the sense that
InstrumentedPool.PoolMetrics.acquiredSize(),
InstrumentedPool.PoolMetrics.idleSize(), InstrumentedPool.PoolMetrics.pendingAcquireSize() and InstrumentedPool.PoolMetrics.allocatedSize() are all at zero
and that the last recorded interaction with the pool (InstrumentedPool.PoolMetrics.secondsSinceLastInteraction())
was more than or exactly duration ago. |
InstrumentedPool.PoolMetrics |
metrics() |
int |
pendingAcquireSize()
Measure the current number of "pending"
acquire Monos in
the Pool. |
long |
secondsSinceLastInteraction()
Measure the duration in seconds since the pool was last interacted with in a meaningful way.
|
Mono<Integer> |
warmup()
Warms up the
Pool, if needed. |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitdispose, withPoolableprotected static final AtomicReferenceFieldUpdater<SimpleDequePool,Deque> IDLE_RESOURCES
public Mono<PooledRef<POOLABLE>> acquire()
PoolPOOLABLE from the pool upon subscription and become responsible for its release.
The object is wrapped in a 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 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 Pool.withPoolable(Function).
The resulting Mono emits the PooledRef as the POOLABLE becomes available. Cancelling the
Subscription before the POOLABLE has been emitted will either avoid object
acquisition entirely or will translate to a release of the POOLABLE.
Once the resource is emitted though, it is the responsibility of the caller to release the poolable object via
the PooledRef 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).
Mono, each subscription to which represents an individual act of acquiring a pooled object and
manually managing its lifecycle from there onPool.withPoolable(Function)public Mono<PooledRef<POOLABLE>> acquire(Duration timeout)
PoolPOOLABLE from the pool upon subscription and become responsible for its release.
The provided 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 Mono.timeout(Duration) operator to
the returned Mono. For a timeout that only applies to resource allocation, build the pool with the standard
Mono.timeout(Duration) operator chained to the allocator.
The object is wrapped in a 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 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 Pool.withPoolable(Function).
The resulting Mono emits the PooledRef as the POOLABLE becomes available. Cancelling the
Subscription before the POOLABLE has been emitted will either avoid object
acquisition entirely or will translate to a release of the POOLABLE.
Once the resource is emitted though, it is the responsibility of the caller to release the poolable object via
the PooledRef 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).
Mono, each subscription to which represents an individual act of acquiring a pooled object and
manually managing its lifecycle from there onPool.withPoolable(Function)public int acquiredSize()
InstrumentedPool.PoolMetricsacquired and are in active use, outside of the
control of the pool until they're released back to it. This number is
only incremented after the resource has been successfully allocated and
is about to be handed off to the subscriber of Pool.acquire().acquiredSize in interface InstrumentedPool.PoolMetricspublic Mono<Void> disposeLater()
PoolMono that represents a lazy asynchronous shutdown of this Pool.
Shutdown doesn't happen until the Mono is subscribed.
Otherwise, it performs the same steps as in the imperative counterpart, Pool.dispose().
If the pool has been already shut down, returns Mono.empty(). Completion of
the Mono indicates completion of the shutdown process.
public int idleSize()
InstrumentedPool.PoolMetricsPool.
Note that some resources might be lazily evicted when they're next considered
for an incoming Pool.acquire() call. Such resources would still count
towards this method.
idleSize in interface InstrumentedPool.PoolMetricspublic Mono<Integer> warmup()
PoolPool, 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 Mono emits the number of extra resources
it created as a result of the allocation minimum.
Note that no work nor allocation is performed until the 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).
Mono that triggers resource warmup and emits the number of warmed up resourcespublic int pendingAcquireSize()
InstrumentedPool.PoolMetricsacquire Monos in
the Pool.
An acquire is in the pending state when it is attempted at a point when no idle resource is available in the pool, and no new resource can be created.
public boolean isDisposed()
public PoolConfig<POOLABLE> config()
Poolconfiguration.
Until 0.3.0, implementors MAY throw an UnsupportedOperationException instead,
although all vanilla reactor-pool implementation do return their configuration.
config in interface Pool<POOLABLE>PoolConfigpublic InstrumentedPool.PoolMetrics metrics()
metrics in interface InstrumentedPool<POOLABLE>InstrumentedPool.PoolMetrics object to be used to get live gauges about the Poolpublic int allocatedSize()
InstrumentedPool.PoolMetricsPool, acquired
or idle.allocatedSize in interface InstrumentedPool.PoolMetricsPoolpublic int getMaxAllocatedSize()
InstrumentedPool.PoolMetricsPool will allow.
A Pool might be unbounded, in which case this method returns Integer.MAX_VALUE.
getMaxAllocatedSize in interface InstrumentedPool.PoolMetricsPoolpublic int getMaxPendingAcquireSize()
InstrumentedPool.PoolMetricsPool.acquire() this Pool can queue in
a pending state when no available resource is immediately handy (and the Pool
cannot allocate more resources).
A Pool pending queue might be unbounded, in which case this method returns
Integer.MAX_VALUE.
getMaxPendingAcquireSize in interface InstrumentedPool.PoolMetricsPoolpublic long secondsSinceLastInteraction()
InstrumentedPool.PoolMetricsInstrumentedPool.PoolMetrics.acquiredSize(), InstrumentedPool.PoolMetrics.idleSize(), InstrumentedPool.PoolMetrics.pendingAcquireSize() and InstrumentedPool.PoolMetrics.allocatedSize())
are also at zero.
The lower the duration, the greater the chances that an interaction could be occurring in parallel to this call. This is why the duration is truncated to the second. A pool implementation that cannot yet support this measurement MAY choose to return -1 seconds instead.
Interactions include background eviction, disposal of the pool, explicit pool warmup, resource acquisition and release (in the default implementation, any interaction triggering the drain loop)...
secondsSinceLastInteraction in interface InstrumentedPool.PoolMetricsInstrumentedPool.PoolMetrics.isInactiveForMoreThan(Duration)public boolean isInactiveForMoreThan(Duration duration)
InstrumentedPool.PoolMetricsInstrumentedPool.PoolMetrics.acquiredSize(),
InstrumentedPool.PoolMetrics.idleSize(), InstrumentedPool.PoolMetrics.pendingAcquireSize() and InstrumentedPool.PoolMetrics.allocatedSize() are all at zero
and that the last recorded interaction with the pool (InstrumentedPool.PoolMetrics.secondsSinceLastInteraction())
was more than or exactly duration ago.isInactiveForMoreThan in interface InstrumentedPool.PoolMetricsInstrumentedPool.PoolMetrics.secondsSinceLastInteraction()