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