MediaWiki REL1_39
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 = $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 if ( $this->now === null ) {
101 $this->now = microtime( true );
102 }
103 return $this->now;
104 }
105
109 public function flush() {
110 foreach ( $this->queuedValues as $ttl => $values ) {
111 $this->store->incr( $values, $ttl );
112 }
113 $this->queuedValues = [];
114 }
115
119 public function __destruct() {
120 $this->flush();
121 }
122
130 public function resetAll( ?array $entities = null ) {
131 $entities = $entities ?? [ new LocalEntityKey ];
132 $this->queuedValues = [];
133 $keys = [];
134 foreach ( $this->metricSpecs as $name => $metricSpec ) {
135 foreach ( $metricSpec->sequences as $seqSpec ) {
136 $timeStep = $seqSpec->timeStep;
137 $ttl = $seqSpec->hardExpiry;
138 $lastBucket = (int)( $this->now() / $timeStep ) + 1;
139 $firstBucket = (int)( ( $this->now() - $ttl ) / $timeStep ) - 1;
140 for ( $bucket = $firstBucket; $bucket <= $lastBucket; $bucket++ ) {
141 foreach ( $entities as $entity ) {
142 $keys[] = $this->store->makeKey(
143 $this->prefixComponents,
144 [ $name, $seqSpec->name, $bucket ],
145 $entity
146 );
147 }
148 }
149 }
150 }
151 $this->store->delete( $keys );
152 }
153}
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.