Class SimpleDequePool<POOLABLE>
- All Implemented Interfaces:
Disposable,InstrumentedPool<POOLABLE>,InstrumentedPool.PoolMetrics,Pool<POOLABLE>
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:
- any thread on which a resource was last allocated
- any thread on which a resource was recently released
- any thread on which an
Pool.acquire()Monowas subscribed
PoolBuilder.acquisitionScheduler(Scheduler) property of the builder can be used.- Author:
- Simon Baslé
-
Nested Class Summary
Nested classes/interfaces inherited from interface reactor.core.Disposable
Disposable.Composite, Disposable.SwapNested classes/interfaces inherited from interface reactor.pool.InstrumentedPool
InstrumentedPool.PoolMetrics -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected static final AtomicReferenceFieldUpdater<SimpleDequePool, @Nullable Deque> -
Method Summary
Modifier and TypeMethodDescriptionacquire()Manually acquire aPOOLABLEfrom the pool upon subscription and become responsible for its release.Manually acquire aPOOLABLEfrom the pool upon subscription and become responsible for its release.intMeasure the current number of resources that have been successfullyacquiredand are in active use, outside of the control of the pool until they're released back to it.intMeasure the current number of allocated resources in thePool, acquired or idle.config()Return the pool'sconfiguration.intGet the maximum number of live resources thisPoolwill allow.intGet the maximum number ofPool.acquire()thisPoolcan queue in a pending state when no available resource is immediately handy (and thePoolcannot allocate more resources).intidleSize()Measure the current number of idle resources in thePool.booleanbooleanisInactiveForMoreThan(Duration duration) A convenience way to check the pool is inactive, in the sense thatInstrumentedPool.PoolMetrics.acquiredSize(),InstrumentedPool.PoolMetrics.idleSize(),InstrumentedPool.PoolMetrics.pendingAcquireSize()andInstrumentedPool.PoolMetrics.allocatedSize()are all at zero and that the last recorded interaction with the pool (InstrumentedPool.PoolMetrics.secondsSinceLastInteraction()) was more than or exactlydurationago.metrics()intMeasure the current number of "pending"acquire Monosin thePool.longMeasure the duration in seconds since the pool was last interacted with in a meaningful way.warmup()Warms up thePool, if needed.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface reactor.pool.Pool
dispose, withPoolable
-
Field Details
-
IDLE_RESOURCES
-
-
Method Details
-
acquire
Description copied from interface:PoolManually acquire aPOOLABLEfrom the pool upon subscription and become responsible for its release. The object is wrapped in aPooledRefwhich 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
PooledRefcan be stored. On the other hand, if the resource and its usage directly expose reactive APIs, you might want to prefer to usePool.withPoolable(Function).The resulting
Monoemits thePooledRefas thePOOLABLEbecomes available. Cancelling theSubscriptionbefore thePOOLABLEhas been emitted will either avoid object acquisition entirely or will translate to areleaseof thePOOLABLE. Once the resource is emitted though, it is the responsibility of the caller to release the poolable object via thePooledRefrelease methodswhen 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).- Returns:
- a
Mono, each subscription to which represents an individual act of acquiring a pooled object and manually managing its lifecycle from there on - See Also:
-
acquire
Description copied from interface:PoolManually acquire aPOOLABLEfrom the pool upon subscription and become responsible for its release. The providedDurationacts 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 theMono.timeout(Duration)operator to the returned Mono. For a timeout that only applies to resource allocation, build the pool with the standardMono.timeout(Duration)operator chained to theallocator.The object is wrapped in a
PooledRefwhich 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
PooledRefcan be stored. On the other hand, if the resource and its usage directly expose reactive APIs, you might want to prefer to usePool.withPoolable(Function).The resulting
Monoemits thePooledRefas thePOOLABLEbecomes available. Cancelling theSubscriptionbefore thePOOLABLEhas been emitted will either avoid object acquisition entirely or will translate to areleaseof thePOOLABLE. Once the resource is emitted though, it is the responsibility of the caller to release the poolable object via thePooledRefrelease methodswhen 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).- Returns:
- a
Mono, each subscription to which represents an individual act of acquiring a pooled object and manually managing its lifecycle from there on - See Also:
-
acquiredSize
public int acquiredSize()Description copied from interface:InstrumentedPool.PoolMetricsMeasure the current number of resources that have been successfullyacquiredand 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 ofPool.acquire().- Specified by:
acquiredSizein interfaceInstrumentedPool.PoolMetrics- Returns:
- the number of acquired resources
-
disposeLater
Description copied from interface:PoolReturns aMonothat represents a lazy asynchronous shutdown of thisPool. Shutdown doesn't happen until theMonoissubscribed. 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 theMonoindicates completion of the shutdown process.- Returns:
- a Mono triggering the shutdown of the pool once subscribed.
-
idleSize
public int idleSize()Description copied from interface:InstrumentedPool.PoolMetricsMeasure the current number of idle resources in thePool.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.- Specified by:
idleSizein interfaceInstrumentedPool.PoolMetrics- Returns:
- the number of idle resources
-
warmup
Description copied from interface:PoolWarms up thePool, if needed. This typically instructs the pool to check for a minimum size and allocate necessary objects when the minimum is not reached. The resultingMonoemits the number of extra resources it created as a result of theallocation minimum.Note that no work nor allocation is performed until the
Monois 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).
- Returns:
- a cold
Monothat triggers resource warmup and emits the number of warmed up resources
-
pendingAcquireSize
public int pendingAcquireSize()Description copied from interface:InstrumentedPool.PoolMetricsMeasure the current number of "pending"acquire Monosin thePool.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.
- Returns:
- the number of pending acquire
-
isDisposed
public boolean isDisposed() -
config
Description copied from interface:PoolReturn the pool'sconfiguration.- Specified by:
configin interfacePool<POOLABLE>- Returns:
- the
PoolConfig
-
metrics
- Specified by:
metricsin interfaceInstrumentedPool<POOLABLE>- Returns:
- a
InstrumentedPool.PoolMetricsobject to be used to get live gauges about thePool
-
allocatedSize
public int allocatedSize()Description copied from interface:InstrumentedPool.PoolMetricsMeasure the current number of allocated resources in thePool, acquired or idle.- Specified by:
allocatedSizein interfaceInstrumentedPool.PoolMetrics- Returns:
- the total number of allocated resources managed by the
Pool
-
getMaxAllocatedSize
public int getMaxAllocatedSize()Description copied from interface:InstrumentedPool.PoolMetricsGet the maximum number of live resources thisPoolwill allow.A
Poolmight be unbounded, in which case this method returnsInteger.MAX_VALUE.- Specified by:
getMaxAllocatedSizein interfaceInstrumentedPool.PoolMetrics- Returns:
- the maximum number of live resources that can be allocated by this
Pool
-
getMaxPendingAcquireSize
public int getMaxPendingAcquireSize()Description copied from interface:InstrumentedPool.PoolMetricsGet the maximum number ofPool.acquire()thisPoolcan queue in a pending state when no available resource is immediately handy (and thePoolcannot allocate more resources).A
Poolpending queue might be unbounded, in which case this method returnsInteger.MAX_VALUE.- Specified by:
getMaxPendingAcquireSizein interfaceInstrumentedPool.PoolMetrics- Returns:
- the maximum number of pending acquire that can be enqueued by this
Pool
-
secondsSinceLastInteraction
public long secondsSinceLastInteraction()Description copied from interface:InstrumentedPool.PoolMetricsMeasure the duration in seconds since the pool was last interacted with in a meaningful way. This is a best effort indicator of pool inactivity, provided the pool counters (InstrumentedPool.PoolMetrics.acquiredSize(),InstrumentedPool.PoolMetrics.idleSize(),InstrumentedPool.PoolMetrics.pendingAcquireSize()andInstrumentedPool.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)...
- Specified by:
secondsSinceLastInteractionin interfaceInstrumentedPool.PoolMetrics- Returns:
- a number of seconds indicative of the time elapsed since last pool interaction
- See Also:
-
isInactiveForMoreThan
Description copied from interface:InstrumentedPool.PoolMetricsA convenience way to check the pool is inactive, in the sense thatInstrumentedPool.PoolMetrics.acquiredSize(),InstrumentedPool.PoolMetrics.idleSize(),InstrumentedPool.PoolMetrics.pendingAcquireSize()andInstrumentedPool.PoolMetrics.allocatedSize()are all at zero and that the last recorded interaction with the pool (InstrumentedPool.PoolMetrics.secondsSinceLastInteraction()) was more than or exactlydurationago.- Specified by:
isInactiveForMoreThanin interfaceInstrumentedPool.PoolMetrics- Returns:
- true if the pool can be considered inactive (see above), false otherwise
- See Also:
-