19
19
* @ingroup Cache
20
20
*/
21
21
22
- use Liuggio \StatsdClient \Factory \StatsdDataFactoryInterface ;
23
22
use Psr \Log \LoggerAwareInterface ;
24
23
use Psr \Log \LoggerInterface ;
25
24
use Psr \Log \NullLogger ;
28
27
use Wikimedia \ObjectCache \BagOStuff ;
29
28
use Wikimedia \ObjectCache \EmptyBagOStuff ;
30
29
use Wikimedia \ObjectCache \IStoreKeyEncoder ;
30
+ use Wikimedia \Stats \StatsFactory ;
31
31
32
32
/**
33
33
* Multi-datacenter aware caching interface
@@ -168,7 +168,7 @@ class WANObjectCache implements
168
168
protected $ processCaches = [];
169
169
/** @var LoggerInterface */
170
170
protected $ logger ;
171
- /** @var StatsdDataFactoryInterface */
171
+ /** @var StatsFactory */
172
172
protected $ stats ;
173
173
/** @var callable|null Function that takes a WAN cache callback and runs it later */
174
174
protected $ asyncHandler ;
@@ -336,7 +336,8 @@ class WANObjectCache implements
336
336
* @param array $params
337
337
* - cache : BagOStuff object for a persistent cache
338
338
* - logger : LoggerInterface object
339
- * - stats : StatsdDataFactoryInterface object
339
+ * - stats : StatsFactory object. Since 1.43, constructing a WANObjectCache object
340
+ * with an IBufferingStatsdDataFactory stats collector will emit a warning.
340
341
* - asyncHandler : A function that takes a callback and runs it later. If supplied,
341
342
* whenever a preemptive refresh would be triggered in getWithSetCallback(), the
342
343
* current cache value is still used instead. However, the async-handler function
@@ -373,9 +374,17 @@ public function __construct( array $params ) {
373
374
}
374
375
375
376
$ this ->setLogger ( $ params ['logger ' ] ?? new NullLogger () );
376
- $ this ->stats = $ params ['stats ' ] ?? new NullStatsdDataFactory ();
377
- $ this ->asyncHandler = $ params ['asyncHandler ' ] ?? null ;
378
377
378
+ if ( isset ( $ params ['stats ' ] ) && $ params ['stats ' ] instanceof IBufferingStatsdDataFactory ) {
379
+ wfDeprecated (
380
+ __METHOD__ ,
381
+ 'Use of StatsdDataFactory is deprecated in 1.43. Use StatsFactory instead. '
382
+ );
383
+ $ params ['stats ' ] = null ;
384
+ }
385
+ $ this ->stats = $ params ['stats ' ] ?? StatsFactory::newNull ();
386
+
387
+ $ this ->asyncHandler = $ params ['asyncHandler ' ] ?? null ;
379
388
$ this ->missLog = array_fill ( 0 , 10 , [ '' , 0.0 ] );
380
389
}
381
390
@@ -812,7 +821,11 @@ final public function set( $key, $value, $ttl = self::TTL_INDEFINITE, array $opt
812
821
$ opts ['creating ' ] ?? false
813
822
);
814
823
815
- $ this ->stats ->increment ( "wanobjectcache. $ keygroup.set. " . ( $ ok ? 'ok ' : 'error ' ) );
824
+ $ this ->stats ->getCounter ( 'wanobjectcache_set_total ' )
825
+ ->setLabel ( 'keygroup ' , $ keygroup )
826
+ ->setLabel ( 'result ' , ( $ ok ? 'ok ' : 'error ' ) )
827
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.set. " . ( $ ok ? 'ok ' : 'error ' ) )
828
+ ->increment ();
816
829
817
830
return $ ok ;
818
831
}
@@ -1065,7 +1078,12 @@ final public function delete( $key, $ttl = self::HOLDOFF_TTL ) {
1065
1078
}
1066
1079
1067
1080
$ keygroup = $ this ->determineKeyGroupForStats ( $ key );
1068
- $ this ->stats ->increment ( "wanobjectcache. $ keygroup.delete. " . ( $ ok ? 'ok ' : 'error ' ) );
1081
+
1082
+ $ this ->stats ->getCounter ( 'wanobjectcache_delete_total ' )
1083
+ ->setLabel ( 'keygroup ' , $ keygroup )
1084
+ ->setLabel ( 'result ' , ( $ ok ? 'ok ' : 'error ' ) )
1085
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.delete. " . ( $ ok ? 'ok ' : 'error ' ) )
1086
+ ->increment ();
1069
1087
1070
1088
return $ ok ;
1071
1089
}
@@ -1224,7 +1242,12 @@ final public function touchCheckKey( $key, $holdoff = self::HOLDOFF_TTL ) {
1224
1242
$ ok = $ this ->relayVolatilePurge ( $ checkSisterKey , $ purge , self ::CHECK_KEY_TTL );
1225
1243
1226
1244
$ keygroup = $ this ->determineKeyGroupForStats ( $ key );
1227
- $ this ->stats ->increment ( "wanobjectcache. $ keygroup.ck_touch. " . ( $ ok ? 'ok ' : 'error ' ) );
1245
+
1246
+ $ this ->stats ->getCounter ( 'wanobjectcache_check_total ' )
1247
+ ->setLabel ( 'keygroup ' , $ keygroup )
1248
+ ->setLabel ( 'result ' , ( $ ok ? 'ok ' : 'error ' ) )
1249
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.ck_touch. " . ( $ ok ? 'ok ' : 'error ' ) )
1250
+ ->increment ();
1228
1251
1229
1252
return $ ok ;
1230
1253
}
@@ -1261,7 +1284,12 @@ final public function resetCheckKey( $key ) {
1261
1284
$ ok = $ this ->relayNonVolatilePurge ( $ checkSisterKey );
1262
1285
1263
1286
$ keygroup = $ this ->determineKeyGroupForStats ( $ key );
1264
- $ this ->stats ->increment ( "wanobjectcache. $ keygroup.ck_reset. " . ( $ ok ? 'ok ' : 'error ' ) );
1287
+
1288
+ $ this ->stats ->getCounter ( 'wanobjectcache_reset_total ' )
1289
+ ->setLabel ( 'keygroup ' , $ keygroup )
1290
+ ->setLabel ( 'result ' , ( $ ok ? 'ok ' : 'error ' ) )
1291
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.ck_reset. " . ( $ ok ? 'ok ' : 'error ' ) )
1292
+ ->increment ();
1265
1293
1266
1294
return $ ok ;
1267
1295
}
@@ -1641,21 +1669,27 @@ private function fetchOrRegenerate( $key, $ttl, $callback, array $opts, array $c
1641
1669
// Get the current key value and its metadata
1642
1670
$ curState = $ this ->fetchKeys ( [ $ key ], $ checkKeys , $ startTime , $ touchedCb )[$ key ];
1643
1671
$ curValue = $ curState [self ::RES_VALUE ];
1672
+
1644
1673
// Use the cached value if it exists and is not due for synchronous regeneration
1645
1674
if ( $ this ->isAcceptablyFreshValue ( $ curState , $ graceTTL , $ minAsOf ) ) {
1646
1675
if ( !$ this ->isLotteryRefreshDue ( $ curState , $ lowTTL , $ ageNew , $ hotTTR , $ startTime ) ) {
1647
- $ this ->stats ->timing (
1648
- "wanobjectcache. $ keygroup.hit.good " ,
1649
- 1e3 * ( $ this ->getCurrentTime () - $ startTime )
1650
- );
1676
+ $ this ->stats ->getTiming ( 'wanobjectcache_getwithset_seconds ' )
1677
+ ->setLabel ( 'keygroup ' , $ keygroup )
1678
+ ->setLabel ( 'result ' , 'hit ' )
1679
+ ->setLabel ( 'reason ' , 'good ' )
1680
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.hit.good " )
1681
+ ->observe ( 1e3 * ( $ this ->getCurrentTime () - $ startTime ) );
1651
1682
1652
1683
return [ $ curValue , $ curState [self ::RES_VERSION ], $ curState [self ::RES_AS_OF ] ];
1653
1684
} elseif ( $ this ->scheduleAsyncRefresh ( $ key , $ ttl , $ callback , $ opts , $ cbParams ) ) {
1654
1685
$ this ->logger ->debug ( "fetchOrRegenerate( $ key): hit with async refresh " );
1655
- $ this ->stats ->timing (
1656
- "wanobjectcache. $ keygroup.hit.refresh " ,
1657
- 1e3 * ( $ this ->getCurrentTime () - $ startTime )
1658
- );
1686
+
1687
+ $ this ->stats ->getTiming ( 'wanobjectcache_getwithset_seconds ' )
1688
+ ->setLabel ( 'keygroup ' , $ keygroup )
1689
+ ->setLabel ( 'result ' , 'hit ' )
1690
+ ->setLabel ( 'reason ' , 'refresh ' )
1691
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.hit.refresh " )
1692
+ ->observe ( 1e3 * ( $ this ->getCurrentTime () - $ startTime ) );
1659
1693
1660
1694
return [ $ curValue , $ curState [self ::RES_VERSION ], $ curState [self ::RES_AS_OF ] ];
1661
1695
} else {
@@ -1687,10 +1721,13 @@ private function fetchOrRegenerate( $key, $ttl, $callback, array $opts, array $c
1687
1721
$ safeMinAsOf = max ( $ minAsOf , $ lastPurgeTime + self ::TINY_POSITIVE );
1688
1722
if ( $ this ->isExtremelyNewValue ( $ volState , $ safeMinAsOf , $ startTime ) ) {
1689
1723
$ this ->logger ->debug ( "fetchOrRegenerate( $ key): volatile hit " );
1690
- $ this ->stats ->timing (
1691
- "wanobjectcache. $ keygroup.hit.volatile " ,
1692
- 1e3 * ( $ this ->getCurrentTime () - $ startTime )
1693
- );
1724
+
1725
+ $ this ->stats ->getTiming ( 'wanobjectcache_getwithset_seconds ' )
1726
+ ->setLabel ( 'keygroup ' , $ keygroup )
1727
+ ->setLabel ( 'result ' , 'hit ' )
1728
+ ->setLabel ( 'reason ' , 'volatile ' )
1729
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.hit.volatile " )
1730
+ ->observe ( 1e3 * ( $ this ->getCurrentTime () - $ startTime ) );
1694
1731
1695
1732
return [ $ volValue , $ volState [self ::RES_VERSION ], $ curState [self ::RES_AS_OF ] ];
1696
1733
}
@@ -1730,19 +1767,26 @@ private function fetchOrRegenerate( $key, $ttl, $callback, array $opts, array $c
1730
1767
// @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive
1731
1768
if ( $ this ->isValid ( $ volValue , $ volState [self ::RES_AS_OF ], $ minAsOf ) ) {
1732
1769
$ this ->logger ->debug ( "fetchOrRegenerate( $ key): returning stale value " );
1733
- $ this ->stats ->timing (
1734
- "wanobjectcache. $ keygroup.hit.stale " ,
1735
- 1e3 * ( $ this ->getCurrentTime () - $ startTime )
1736
- );
1770
+
1771
+ $ this ->stats ->getTiming ( 'wanobjectcache_getwithset_seconds ' )
1772
+ ->setLabel ( 'keygroup ' , $ keygroup )
1773
+ ->setLabel ( 'result ' , 'hit ' )
1774
+ ->setLabel ( 'reason ' , 'stale ' )
1775
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.hit.stale " )
1776
+ ->observe ( 1e3 * ( $ this ->getCurrentTime () - $ startTime ) );
1737
1777
1738
1778
return [ $ volValue , $ volState [self ::RES_VERSION ], $ curState [self ::RES_AS_OF ] ];
1739
1779
} elseif ( $ busyValue !== null ) {
1740
1780
$ miss = is_infinite ( $ minAsOf ) ? 'renew ' : 'miss ' ;
1741
1781
$ this ->logger ->debug ( "fetchOrRegenerate( $ key): busy $ miss " );
1742
- $ this ->stats ->timing (
1743
- "wanobjectcache. $ keygroup. $ miss.busy " ,
1744
- 1e3 * ( $ this ->getCurrentTime () - $ startTime )
1745
- );
1782
+
1783
+ $ this ->stats ->getTiming ( 'wanobjectcache_getwithset_seconds ' )
1784
+ ->setLabel ( 'keygroup ' , $ keygroup )
1785
+ ->setLabel ( 'result ' , $ miss )
1786
+ ->setLabel ( 'reason ' , 'busy ' )
1787
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup. $ miss.busy " )
1788
+ ->observe ( 1e3 * ( $ this ->getCurrentTime () - $ startTime ) );
1789
+
1746
1790
$ placeholderValue = $ this ->resolveBusyValue ( $ busyValue );
1747
1791
1748
1792
return [ $ placeholderValue , $ version , $ curState [self ::RES_AS_OF ] ];
@@ -1773,7 +1817,11 @@ private function fetchOrRegenerate( $key, $ttl, $callback, array $opts, array $c
1773
1817
1774
1818
// How long it took to generate the value
1775
1819
$ walltime = max ( $ postCallbackTime - $ preCallbackTime , 0.0 );
1776
- $ this ->stats ->timing ( "wanobjectcache. $ keygroup.regen_walltime " , 1e3 * $ walltime );
1820
+
1821
+ $ this ->stats ->getTiming ( 'wanobjectcache_regen_seconds ' )
1822
+ ->setLabel ( 'keygroup ' , $ keygroup )
1823
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.regen_walltime " )
1824
+ ->observe ( 1e3 * $ walltime );
1777
1825
1778
1826
// Attempt to save the newly generated value if applicable
1779
1827
if (
@@ -1782,7 +1830,11 @@ private function fetchOrRegenerate( $key, $ttl, $callback, array $opts, array $c
1782
1830
// Current thread was not raced out of a regeneration lock or key is tombstoned
1783
1831
( !$ useRegenerationLock || $ hasLock || $ isKeyTombstoned )
1784
1832
) {
1785
- $ this ->stats ->timing ( "wanobjectcache. $ keygroup.regen_set_delay " , 1e3 * $ elapsed );
1833
+ $ this ->stats ->getTiming ( 'wanobjectcache_regen_set_delay_seconds ' )
1834
+ ->setLabel ( 'keygroup ' , $ keygroup )
1835
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup.regen_set_delay " )
1836
+ ->observe ( 1e3 * $ elapsed );
1837
+
1786
1838
// If the key is write-holed then use the (volatile) interim key as an alternative
1787
1839
if ( $ isKeyTombstoned ) {
1788
1840
$ this ->setInterimValue (
@@ -1817,10 +1869,13 @@ private function fetchOrRegenerate( $key, $ttl, $callback, array $opts, array $c
1817
1869
1818
1870
$ miss = is_infinite ( $ minAsOf ) ? 'renew ' : 'miss ' ;
1819
1871
$ this ->logger ->debug ( "fetchOrRegenerate( $ key): $ miss, new value computed " );
1820
- $ this ->stats ->timing (
1821
- "wanobjectcache. $ keygroup. $ miss.compute " ,
1822
- 1e3 * ( $ this ->getCurrentTime () - $ startTime )
1823
- );
1872
+
1873
+ $ this ->stats ->getTiming ( 'wanobjectcache_getwithset_seconds ' )
1874
+ ->setLabel ( 'keygroup ' , $ keygroup )
1875
+ ->setLabel ( 'result ' , $ miss )
1876
+ ->setLabel ( 'reason ' , 'compute ' )
1877
+ ->copyToStatsdAt ( "wanobjectcache. $ keygroup. $ miss.compute " )
1878
+ ->observe ( 1e3 * ( $ this ->getCurrentTime () - $ startTime ) );
1824
1879
1825
1880
return [ $ value , $ version , $ curState [self ::RES_AS_OF ] ];
1826
1881
}
0 commit comments