MediaWiki REL1_40
WRStatsWriter.php
Go to the documentation of this file.
1<?php
2
3namespace Wikimedia\WRStats;
4
13 private $store;
15 private $metricSpecs;
17 private $queuedValues = [];
19 private $now;
21 private $prefixComponents;
22
30 public function __construct( StatsStore $store, $specs, $prefix ) {
31 $this->store = $store;
32 $this->metricSpecs = [];
33 foreach ( $specs as $name => $spec ) {
34 $this->metricSpecs[$name] = new MetricSpec( $spec );
35 }
36 $this->prefixComponents = is_array( $prefix ) ? $prefix : [ $prefix ];
37 if ( !count( $this->prefixComponents ) ) {
38 throw new WRStatsError( __METHOD__ .
39 ': there must be at least one prefix component' );
40 }
41 }
42
50 public function incr( $name, ?EntityKey $entity = null, $value = 1 ) {
51 $metricSpec = $this->metricSpecs[$name] ?? null;
52 $entity ??= new LocalEntityKey;
53 if ( $metricSpec === null ) {
54 throw new WRStatsError( __METHOD__ . ": Unrecognised metric \"$name\"" );
55 }
56 $res = $metricSpec->resolution;
57 $scaledValue = $value / $res;
58
59 foreach ( $metricSpec->sequences as $seqSpec ) {
60 $timeStep = $seqSpec->timeStep;
61 $timeBucket = (int)( $this->now() / $timeStep );
62 $key = $this->store->makeKey(
63 $this->prefixComponents,
64 [ $name, $seqSpec->name, $timeBucket ],
65 $entity
66 );
67
68 $ttl = $seqSpec->hardExpiry;
69
70 if ( !isset( $this->queuedValues[$ttl][$key] ) ) {
71 $this->queuedValues[$ttl][$key] = 0;
72 }
73 $this->queuedValues[$ttl][$key] += (int)round( $scaledValue );
74 }
75 }
76
82 public function setCurrentTime( $now ) {
83 $this->now = $now;
84 }
85
92 public function resetCurrentTime() {
93 $this->now = null;
94 }
95
99 private function now() {
100 $this->now ??= microtime( true );
101 return $this->now;
102 }
103
107 public function flush() {
108 foreach ( $this->queuedValues as $ttl => $values ) {
109 $this->store->incr( $values, $ttl );
110 }
111 $this->queuedValues = [];
112 }
113
117 public function __destruct() {
118 $this->flush();
119 }
120
128 public function resetAll( ?array $entities = null ) {
129 $entities ??= [ new LocalEntityKey ];
130 $this->queuedValues = [];
131 $keys = [];
132 foreach ( $this->metricSpecs as $name => $metricSpec ) {
133 foreach ( $metricSpec->sequences as $seqSpec ) {
134 $timeStep = $seqSpec->timeStep;
135 $ttl = $seqSpec->hardExpiry;
136 $lastBucket = (int)( $this->now() / $timeStep ) + 1;
137 $firstBucket = (int)( ( $this->now() - $ttl ) / $timeStep ) - 1;
138 for ( $bucket = $firstBucket; $bucket <= $lastBucket; $bucket++ ) {
139 foreach ( $entities as $entity ) {
140 $keys[] = $this->store->makeKey(
141 $this->prefixComponents,
142 [ $name, $seqSpec->name, $bucket ],
143 $entity
144 );
145 }
146 }
147 }
148 }
149 $this->store->delete( $keys );
150 }
151}
Base class for entity keys.
Definition EntityKey.php:13
Entity key with global=false.
Class representation of normalized metric specifications.
Exception class for errors thrown by the WRStats library.
Writers gather a batch of increment operations and then commit them when flush() is called,...
resetCurrentTime()
Reset the stored current time.
incr( $name, ?EntityKey $entity=null, $value=1)
Queue an increment operation.
__construct(StatsStore $store, $specs, $prefix)
resetAll(?array $entities=null)
Delete all stored metrics corresponding to the specs supplied to the constructor, resetting the count...
__destruct()
Commit the batch of increment operations.
setCurrentTime( $now)
Set the time to be used as the current time.
flush()
Commit the batch of increment operations.
The narrow interface WRStats needs into a memcached-like key-value store.