1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
<?php
namespace Wikimedia\WRStats;
/**
* A class representing a batch of increment/peek operations on a WRStatsRateLimiter
*
* @since 1.39
*/
class LimitBatch {
/** @var WRStatsRateLimiter */
private $limiter;
/** @var int */
private $defaultAmount;
/** @var LimitOperation[] */
private $operations = [];
/**
* @internal Use WRStatsFactory::createRateLimiter()->createBatch() instead
* @param WRStatsRateLimiter $limiter
* @param int $defaultAmount
*/
public function __construct(
WRStatsRateLimiter $limiter,
$defaultAmount
) {
$this->limiter = $limiter;
$this->defaultAmount = $defaultAmount;
}
/**
* Construct a local entity key and queue an operation for it.
*
* @param string $condName The condition name to be incremented/tested,
* which must match one of the ones passed to createRateLimiter()
* @param mixed $components Entity key component or array of components
* @param int|null $amount The amount to increment by, or null to use the default
* @return $this
*/
public function localOp( $condName, $components = [], $amount = null ) {
if ( !is_array( $components ) ) {
$components = [ $components ];
}
$this->queueOp(
$condName,
new LocalEntityKey( array_merge( [ $condName ], $components ) ),
$amount
);
return $this;
}
/**
* Construct a global entity key and queue an operation for it.
*
* @param string $condName The condition name to be incremented/tested,
* which must match one of the ones passed to createRateLimiter()
* @param mixed $components Entity key components
* @param int|null $amount The amount, or null to use the default
* @return $this
*/
public function globalOp( $condName, $components = [], $amount = null ) {
if ( !is_array( $components ) ) {
$components = [ $components ];
}
$this->queueOp(
$condName,
new GlobalEntityKey( array_merge( [ $condName ], $components ) ),
$amount
);
return $this;
}
private function queueOp( $type, $entity, $amount ) {
$amount ??= $this->defaultAmount;
if ( isset( $this->operations[$type] ) ) {
throw new WRStatsError( 'Cannot queue multiple actions of the same type, ' .
'because the result array is indexed by type' );
}
$this->operations[$type] = new LimitOperation( $type, $entity, $amount );
}
/**
* Execute the batch, checking each operation against the defined limit,
* but don't actually increment the metrics.
*
* @return LimitBatchResult
*/
public function peek() {
return $this->limiter->peekBatch( $this->operations );
}
/**
* Execute the batch, unconditionally incrementing all the specified metrics.
*/
public function incr() {
$this->limiter->incrBatch( $this->operations );
}
/**
* Execute the batch, checking each operation against the defined limit.
* If all operations are allowed, all metrics will be incremented. If some
* of the operations exceed the limit, none of the metrics will be
* incremented.
*
* @return LimitBatchResult
*/
public function tryIncr() {
return $this->limiter->tryIncrBatch( $this->operations );
}
}
|