public final class SamplingAllocationStrategy extends Object implements AllocationStrategy
AllocationStrategy
that delegates to an underlying AllocationStrategy
and samples
the getPermits(int)
and returnPermits(int)
methods.
Only a given percentage of calls are sampled, and these are stored as stacktraces in the sampling strategy.
If a AllocationStrategy.returnPermits(int)
call fails, a new IllegalArgumentException
is thrown with a composite cause that represents all the sampled calls (see Exceptions.unwrapMultiple(Throwable)
).
The two types of calls are sampled separately. The reservoir sampling algorithm is used to instantiate a sampling decision
bitset over 100 slots, which are then applied to windows of 100 calls.
Access to the delegate
field is possible, as well as gettingSamplingRate
/returningSamplingRate
configuration fields and gettingSamples
/returningSamples
collections.
Modifier and Type | Field and Description |
---|---|
AllocationStrategy |
delegate
The delegate
AllocationStrategy backing this sampling strategy. |
LinkedList<Throwable> |
gettingSamples
The list of samples for
getPermits(int) calls, as Throwable that trace back
to the callers of the sampled calls. |
double |
gettingSamplingRate
The configured sampling rate for
getPermits(int) calls, as a double between 0d and 1d (percentage). |
LinkedList<Throwable> |
returningSamples
The list of samples for
returnPermits(int) calls, as Throwable that trace back
to the callers of the sampled calls. |
double |
returningSamplingRate
The configured sampling rate for
returnPermits(int) calls, as a double between 0d and 1d (percentage). |
Modifier and Type | Method and Description |
---|---|
int |
estimatePermitCount()
Best-effort peek at the state of the strategy which indicates roughly how many more resources can currently be
allocated.
|
int |
getPermits(int desired)
Try to get the permission to allocate a
desired positive number of new resources. |
int |
permitGranted() |
int |
permitMaximum() |
int |
permitMinimum()
Return the minimum number of permits this strategy tries to maintain granted
(reflecting a minimal size for the pool), or
0 for scale-to-zero. |
void |
returnPermits(int returned)
Update the strategy to indicate that N resources were discarded from the
Pool , potentially leaving space
for N new ones to be allocated. |
static SamplingAllocationStrategy |
sizeBetweenWithSampling(int min,
int max,
double getPermitsSamplingRate,
double returnPermitsSamplingRate)
An
SamplingAllocationStrategy that wraps a sizeBetween AllocationStrategy
and samples calls to AllocationStrategy.getPermits(int) and AllocationStrategy.returnPermits(int) . |
int |
warmupParallelism()
Return the concurrency level used when the allocator is subscribed to during the warmup phase, if any.
|
static SamplingAllocationStrategy |
withSampling(AllocationStrategy delegate,
double getPermitsSamplingRate,
double returnPermitsSamplingRate)
An
AllocationStrategy that wraps a delegate and samples calls to AllocationStrategy.getPermits(int)
and AllocationStrategy.returnPermits(int) . |
public final AllocationStrategy delegate
AllocationStrategy
backing this sampling strategy.public final LinkedList<Throwable> gettingSamples
getPermits(int)
calls, as Throwable
that trace back
to the callers of the sampled calls.public final double gettingSamplingRate
getPermits(int)
calls, as a double between 0d and 1d (percentage).public final LinkedList<Throwable> returningSamples
returnPermits(int)
calls, as Throwable
that trace back
to the callers of the sampled calls.public final double returningSamplingRate
returnPermits(int)
calls, as a double between 0d and 1d (percentage).public static SamplingAllocationStrategy sizeBetweenWithSampling(int min, int max, double getPermitsSamplingRate, double returnPermitsSamplingRate)
SamplingAllocationStrategy
that wraps a sizeBetween
AllocationStrategy
and samples calls to AllocationStrategy.getPermits(int)
and AllocationStrategy.returnPermits(int)
.min
- the minimum number of permits (see PoolBuilder.sizeBetween(int, int)
)max
- the maximum number of permits (see PoolBuilder.sizeBetween(int, int)
)getPermitsSamplingRate
- the sampling rate for AllocationStrategy.getPermits(int)
calls (0.0d to 1.0d)returnPermitsSamplingRate
- the sampling rate for AllocationStrategy.returnPermits(int)
calls (0.0d to 1.0d)AllocationStrategy
that otherwise behaves like the PoolBuilder.sizeBetween(int, int)
strategypublic static SamplingAllocationStrategy withSampling(AllocationStrategy delegate, double getPermitsSamplingRate, double returnPermitsSamplingRate)
AllocationStrategy
that wraps a delegate
and samples calls to AllocationStrategy.getPermits(int)
and AllocationStrategy.returnPermits(int)
. Only a given percentage of calls are sampled, and these are stored as stacktraces
in the sampling strategy. If a AllocationStrategy.returnPermits(int)
call fails, a new IllegalArgumentException
is thrown with a composite cause that represents all the sampled calls (see Exceptions.unwrapMultiple(Throwable)
).
The two types of calls are sampled separately. The reservoir sampling algorithm is used to instantiate a sampling decision bitset over 100 slots, which are then applied live to windows of 100 calls.
delegate
- the underlying AllocationStrategy
getPermitsSamplingRate
- the sampling rate for AllocationStrategy.getPermits(int)
calls (0.0d to 1.0d)returnPermitsSamplingRate
- the sampling rate for AllocationStrategy.returnPermits(int)
calls (0.0d to 1.0d)AllocationStrategy
that otherwise behaves like the delegate
public int getPermits(int desired)
AllocationStrategy
desired
positive number of new resources. Returns the permissible
number of resources which MUST be created (otherwise the internal live counter of the strategy might be off).
This permissible number might be zero, and it can also be a greater number than desired
, which could for
example denote a minimum warmed-up size for the pool to maintain (see below).
Once a resource is discarded from the pool, it must update the strategy using AllocationStrategy.returnPermits(int)
(which can happen in batches or with value 1).
For the warming up case, the typical pattern would be to call this method with a desired
of zero.
getPermits
in interface AllocationStrategy
desired
- the desired number of new resourcesdesired
public void returnPermits(int returned)
AllocationStrategy
Pool
, potentially leaving space
for N new ones to be allocated. Users MUST ensure that this method isn't called with a value greater than the
number of held permits it has.
Some strategy MIGHT throw an IllegalArgumentException
if it can be determined the number of returned permits
is not consistent with the strategy's limits and delivered permits.
returnPermits
in interface AllocationStrategy
public int estimatePermitCount()
AllocationStrategy
AllocationStrategy.getPermits(int)
for an atomic permission.estimatePermitCount
in interface AllocationStrategy
public int permitGranted()
permitGranted
in interface AllocationStrategy
Integer.MAX_VALUE
public int permitMinimum()
AllocationStrategy
0
for scale-to-zero.permitMinimum
in interface AllocationStrategy
0
public int permitMaximum()
permitMaximum
in interface AllocationStrategy
Integer.MAX_VALUE
for unboundedpublic int warmupParallelism()
AllocationStrategy
The number of resources created concurrently will not exceed the value returned by warmupParallelism()
.
If the concurrency level is set to 1, pre-allocation of resources 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.
Defaults to 1
warmupParallelism
in interface AllocationStrategy
1
by default