Class PoolBuilder<T,CONF extends PoolConfig<T>>
- Type Parameters:
T- the type of elements in the producedPoolCONF- thePoolConfigflavor this builder will provide to the createdPool
- Author:
- Simon Baslé
-
Method Summary
Modifier and TypeMethodDescriptionacquisitionScheduler(Scheduler acquisitionScheduler) allocationStrategy(AllocationStrategy allocationStrategy) Limits in how many resources can be allocated and managed by thePoolare driven by the providedAllocationStrategy.Build a custom flavor ofPool, given a Pool factoryFunctionthat is provided with aPoolConfigcopy of this builder's configuration.Construct a default reactor pool with the builder's configuration.<P extends InstrumentedPool<T>>
PbuildPoolAndDecorateWith(Function<? super InstrumentedPool<T>, P> decorator) Construct a default reactor pool with the builder's configuration, then wrap it into a decorator implementation using the providedFunction.Set theClockto use for timestamps, notably marking the times at which a resource is allocated, released and acquired.destroyHandler(Function<T, ? extends Publisher<Void>> destroyHandler) evictInBackground(Duration evictionInterval) Enable background eviction so thatevictionPredicateis regularly applied to elements that are idle in the pool when there is no pool activity (i.e.evictInBackground(Duration evictionInterval, Scheduler reaperTaskScheduler) Enable background eviction so thatevictionPredicateis regularly applied to elements that are idle in the pool when there is no pool activity (i.e.Disable background eviction entirely, so thatevictionPredicateis only checked uponacquireandrelease(ie only when there is pool activity).evictionIdle(Duration maxIdleTime) Set theeviction predicateto cause eviction (ie returnstrue) of resources that have been idle (ie released and available in thePool) for more than thettlDuration(inclusive).evictionPredicate(BiPredicate<T, PooledRefMetadata> evictionPredicate) Provide an evictionBiPredicatethat allows to decide if a resource is fit for being placed in thePool.<CONF2 extends PoolConfig<T>>
PoolBuilder<T, CONF2> extraConfiguration(Function<? super CONF, CONF2> configModifier) Add implementation-specific configuration, changing the type ofPoolConfigpassed to thePoolfactory inbuild(Function).static <T> PoolBuilder<T, PoolConfig<T>> Start building aPoolby describing how new objects are to be asynchronously allocated.Configure the pool so that if there are idle resources (ie pool is under-utilized), the nextPool.acquire()will get the Least Recently Used resource (LRU, ie.Configure the pool so that if there are idle resources (ie pool is under-utilized), the nextPool.acquire()will get the Most Recently Used resource (MRU, ie.idleResourceReuseOrder(boolean isLru) Configure the order in which idle resources are used when the nextPool.acquire()is performed (while the pool is under-utilized).maxLifeTime(Duration maxLifeTime) Set the maximum lifetime for pooled resources.maxLifeTimeVariance(double variancePercent) Set a variance percentage formaxLifeTime(Duration), introducing per-resource jitter to prevent simultaneous expiry of resources created around the same time.maxPendingAcquire(int maxPending) Set the maximum number of subscribedPool.acquire()Monos that can be in a pending state (ie they wait for a resource to be released, as no idle resource was immediately available, and the pool add already allocated the maximum permitted amount).Uncap the number of subscribedPool.acquire()Monos that can be in a pending state (ie they wait for a resource to be released, as no idle resource was immediately available, and the pool add already allocated the maximum permitted amount).metricsRecorder(PoolMetricsRecorder recorder) Set up the optionalPoolMetricsRecorderforPoolto use for instrumentation purposes.pendingAcquireTimer(BiFunction<Runnable, Duration, Disposable> pendingAcquireTimer) Define how timeouts are scheduled when aPool.acquire(Duration)call is made and the acquisition is pending.releaseHandler(Function<T, ? extends Publisher<Void>> releaseHandler) sizeBetween(int min, int max) sizeBetween(int min, int max, int warmupParallelism) Replace theAllocationStrategywith one that lets thePoolallocate new resources when no idle resource is available, without limit.
-
Method Details
-
from
Start building aPoolby describing how new objects are to be asynchronously allocated. Note that thePublisherallocatoris subscribed to each time a new resource is needed and will be cancelled past the first received element (unless it is already aMono).Adapting from blocking code is only acceptable if ensuring the work is offset on another
Scheduler(eg. a constructor materialized viaMono.fromCallable(Callable)should be augmented withMono.subscribeOn(Scheduler)). -
acquisitionScheduler
Provide aSchedulerthat can optionally be used by aPoolto deliver its resources in a more deterministic (albeit potentially less efficient) way, thread-wise. Other implementations MAY completely ignore this parameter.Defaults to
Schedulers.immediate(). -
pendingAcquireTimer
public PoolBuilder<T,CONF> pendingAcquireTimer(BiFunction<Runnable, Duration, Disposable> pendingAcquireTimer) Define how timeouts are scheduled when aPool.acquire(Duration)call is made and the acquisition is pending. i.e. there is no idle resource and no new resource can be created currently, so a timeout is scheduled using the provided function.By default, the
Schedulers.parallel()scheduler is used.- Parameters:
pendingAcquireTimer- the function to apply when scheduling timers for acquisitions that are added to the pending queue.- Returns:
- this
Poolbuilder
-
allocationStrategy
Limits in how many resources can be allocated and managed by thePoolare driven by the providedAllocationStrategy. This is a customization escape hatch that replaces the last configured strategy, but most cases should be covered by thesizeBetween(int, int)orsizeUnbounded()pre-made strategies.Without a call to any of these 3 methods, the builder defaults to an
unbounded creation of resources, although it is not a recommended one.- Parameters:
allocationStrategy- theAllocationStrategyto use- Returns:
- this
Poolbuilder - See Also:
-
destroyHandler
Provide ahandlerthat will derive a destroyPublisherwhenever a resource isn't fit for usage anymore (either through eviction, manual invalidation, or because something went wrong with it). The destroy procedure is applied asynchronously and errors are swallowed.Defaults to recognizing
DisposableandCloseableelements and disposing them. -
evictionIdle
Set theeviction predicateto cause eviction (ie returnstrue) of resources that have been idle (ie released and available in thePool) for more than thettlDuration(inclusive). Such a predicate could be used to evict too idle objects when next encountered by anPool.acquire().This replaces any
evictionPredicate(BiPredicate)previously set. If you need to combine idle predicate with more custom logic, prefer directly providing aBiPredicate. Note that the idle predicate from this method is written as(poolable, meta) -> meta.idleTime() >= maxIdleTime.toMillis(). -
evictionPredicate
Provide an evictionBiPredicatethat allows to decide if a resource is fit for being placed in thePool. This can happen whenever a resource isreleasedback to thePool(after it was processed by thereleaseHandler(Function)), but also when beingacquiredfrom the pool (triggering a second pass if the object is found to be unfit, eg. it has been idle for too long). Finally, some pool implementations MAY implement a reaper thread mechanism that detect idle resources through this predicate and destroy them.Defaults to never evicting (a
BiPredicatethat always returns false).In case some asynchronous verification of the health of a resource is needed, one possible approach is to rely on
Pool.acquire()andPooledRef.invalidate()instead of the evictionPredicate: performing the check in a flatMap after having acquired the resource, then further chain an invalidate call if the resource is not healthy. The acquisition should then be retried, and a good way of doing so is by continuing the invalidate call with aMono.error(Throwable)with a custom exception which would trigger an outerMono.retryWhen(Retry). -
evictInBackgroundDisabled
Disable background eviction entirely, so thatevictionPredicateis only checked uponacquireandrelease(ie only when there is pool activity).- Returns:
- this
Poolbuilder - See Also:
-
evictInBackground
Enable background eviction so thatevictionPredicateis regularly applied to elements that are idle in the pool when there is no pool activity (i.e.acquireandrelease).Providing an
evictionIntervalofzerois similar todisablingbackground eviction.Background eviction support is optional: although all vanilla reactor-pool implementations DO support it, other implementations MAY ignore it. The background eviction process can be implemented in a best effort fashion, backing off if it detects any pool activity.
- Returns:
- this
Poolbuilder - See Also:
-
evictInBackground
public PoolBuilder<T,CONF> evictInBackground(Duration evictionInterval, Scheduler reaperTaskScheduler) Enable background eviction so thatevictionPredicateis regularly applied to elements that are idle in the pool when there is no pool activity (i.e.acquireandrelease).Providing an
evictionIntervalofzerois similar todisablingbackground eviction.Background eviction support is optional: although all vanilla reactor-pool implementations DO support it, other implementations MAY ignore it. The background eviction process can be implemented in a best effort fashion, backing off if it detects any pool activity.
- Returns:
- this
Poolbuilder - See Also:
-
maxLifeTime
Set the maximum lifetime for pooled resources. Resources that have been alive for longer than this duration will be evicted on acquire, release, or during background eviction.When configured, this is composed with any
evictionPredicate(BiPredicate)using OR logic — a resource is evicted if either condition triggers.Defaults to
Duration.ZERO(disabled).- Parameters:
maxLifeTime- maximum resource lifetime (resolution: ms), orDuration.ZEROto disable- Returns:
- this
Poolbuilder - Since:
- 1.2.4
- See Also:
-
maxLifeTimeVariance
Set a variance percentage formaxLifeTime(Duration), introducing per-resource jitter to prevent simultaneous expiry of resources created around the same time.The effective max lifetime for each resource will be in the range:
[maxLifeTime * (1 - variance/100), maxLifeTime], spreading resource renewal over a window instead of a single point in time.For example, with a
maxLifeTimeof 60 seconds and a variance of 2.5%, resources would expire between 58.5s and 60s.Only meaningful when
maxLifeTime(Duration)is configured (non-zero). Defaults to 0 (no variance — all resources expire at exactlymaxLifeTime).- Parameters:
variancePercent- percentage of maxLifeTime to use as the variance range (0–100)- Returns:
- this
Poolbuilder - Since:
- 1.2.4
- See Also:
-
maxPendingAcquire
Set the maximum number of subscribedPool.acquire()Monos that can be in a pending state (ie they wait for a resource to be released, as no idle resource was immediately available, and the pool add already allocated the maximum permitted amount). Set to0to immediately fail all such acquisition attempts. Set to-1to deactivate (or prefer using the more explicitmaxPendingAcquireUnbounded()).Default to -1.
- Parameters:
maxPending- the maximum number of registered acquire monos to keep in a pending queue- Returns:
- a builder of
Poolwith a maximum pending queue size.
-
maxPendingAcquireUnbounded
Uncap the number of subscribedPool.acquire()Monos that can be in a pending state (ie they wait for a resource to be released, as no idle resource was immediately available, and the pool add already allocated the maximum permitted amount).This is the default.
- Returns:
- a builder of
Poolwith no maximum pending queue size
-
clock
Set theClockto use for timestamps, notably marking the times at which a resource is allocated, released and acquired. TheClock.millis()method is used for this purpose, which produces timestamps and durations in milliseconds for eg. theevictionPredicate(BiPredicate).These durations can also be exported as metrics, through the
metricsRecorder, but having a separateClockseparates the concerns and allows to disregard metrics without crippling eviction. -
metricsRecorder
Set up the optionalPoolMetricsRecorderforPoolto use for instrumentation purposes.- Parameters:
recorder- thePoolMetricsRecorder- Returns:
- this
Poolbuilder
-
releaseHandler
Provide ahandlerthat will derive a resetPublisherwhenever a resource is released. The reset procedure is applied asynchronously before vetting the object throughevictionPredicate. If the reset Publisher couldn't put the resource back in a usable state, it will bedestroyed.Defaults to not resetting anything.
-
sizeBetween
Replace theAllocationStrategywith one that lets thePoolallocate betweenminandmaxresources. When acquiring and there is no available resource, the pool should strive to warm up enough resources to reachminlive resources before serving the acquire with (one of) the newly created resource(s). At the same time it MUST NOT allocate any resource if that would bring the number of live resources over themax, rejecting further allocations until some resources have beenreleased.Pre-allocation of warmed-up resources, if any, will be performed sequentially by subscribing to the allocator one at a time. The process waits for a resource to be created before subscribing again to the allocator. This sequence continues until all pre-allocated resources have been successfully created.
- Parameters:
min- the minimum number of live resources to keep in the pool (can be best effort)max- the maximum number of live resources to keep in the pool. useInteger.MAX_VALUEwhen you only need a minimum and no upper bound- Returns:
- this
Poolbuilder - See Also:
-
sizeBetween
Replace theAllocationStrategywith one that lets thePoolallocate betweenminandmaxresources. When acquiring and there is no available resource, the pool should strive to warm up enough resources to reachminlive resources before serving the acquire with (one of) the newly created resource(s). At the same time it MUST NOT allocate any resource if that would bring the number of live resources over themax, rejecting further allocations until some resources have beenreleased.- Parameters:
min- the minimum number of live resources to keep in the pool (can be best effort)max- the maximum number of live resources to keep in the pool. useInteger.MAX_VALUEwhen you only need a minimum and no upper boundwarmupParallelism- Specifies the concurrency level used when the allocator is subscribed to during the warmup phase, if any. During warmup, resources that can be pre-allocated will be created eagerly, but at mostwarmupParallelismresources are subscribed to at the same time. AwarmupParallelismof 1 means that pre-allocation of resources is achieved by sequentially subscribing to the allocator, waiting for a resource to be created before subscribing a next time to the allocator, and so on until the last allocation completes.- Returns:
- this
Poolbuilder - Since:
- 1.0.1
- See Also:
-
sizeUnbounded
Replace theAllocationStrategywith one that lets thePoolallocate new resources when no idle resource is available, without limit.Note this is the default, if no previous call to
allocationStrategy(AllocationStrategy)orsizeBetween(int, int)has been made on thisPoolBuilder.- Returns:
- this
Poolbuilder - See Also:
-
idleResourceReuseLruOrder
Configure the pool so that if there are idle resources (ie pool is under-utilized), the nextPool.acquire()will get the Least Recently Used resource (LRU, ie. the resource that was released first among the current idle resources).- Returns:
- this
Poolbuilder
-
idleResourceReuseMruOrder
Configure the pool so that if there are idle resources (ie pool is under-utilized), the nextPool.acquire()will get the Most Recently Used resource (MRU, ie. the resource that was released last among the current idle resources).- Returns:
- this
Poolbuilder
-
idleResourceReuseOrder
Configure the order in which idle resources are used when the nextPool.acquire()is performed (while the pool is under-utilized). Allows to chose between the Least Recently Used order whentrue(LRU, ie. the resource that was released first among the current idle resources, the default) and Most Recently Used order (MRU, ie. the resource that was released last among the current idle resources).- Parameters:
isLru-truefor LRU (the default) orfalsefor MRU- Returns:
- this
Poolbuilder - See Also:
-
extraConfiguration
public <CONF2 extends PoolConfig<T>> PoolBuilder<T,CONF2> extraConfiguration(Function<? super CONF, CONF2> configModifier) Add implementation-specific configuration, changing the type ofPoolConfigpassed to thePoolfactory inbuild(Function).- Type Parameters:
CONF2- new type for the configuration- Parameters:
configModifier-Functionto transform the type ofPoolConfigcreated by this builder for the benefit of the pool factory, allowing for custom implementations with custom configurations- Returns:
- a new PoolBuilder that now produces a different type of
PoolConfig
-
buildPool
Construct a default reactor pool with the builder's configuration.- Returns:
- an
InstrumentedPool
-
buildPoolAndDecorateWith
public <P extends InstrumentedPool<T>> P buildPoolAndDecorateWith(Function<? super InstrumentedPool<T>, P> decorator) Construct a default reactor pool with the builder's configuration, then wrap it into a decorator implementation using the providedFunction.- Type Parameters:
P- the type of decorated pool, must extendInstrumentedPool(with same type of resource)- Parameters:
decorator- a decoratorFunctionreturning a decorated version of theInstrumentedPool- Returns:
- the built-then-decorated pool
-
build
Build a custom flavor ofPool, given a Pool factoryFunctionthat is provided with aPoolConfigcopy of this builder's configuration.- Parameters:
poolFactory- the factory of pool implementation- Returns:
- the
Pool
-