Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 27 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
CacheBackedImageRecommendationProvider | |
0.00% |
0 / 27 |
|
0.00% |
0 / 4 |
42 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
get | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
getWithSetCallback | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
12 | |||
makeKey | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace GrowthExperiments\NewcomerTasks\AddImage; |
4 | |
5 | use GrowthExperiments\NewcomerTasks\TaskType\ImageRecommendationBaseTaskType; |
6 | use GrowthExperiments\NewcomerTasks\TaskType\TaskType; |
7 | use MediaWiki\Linker\LinkTarget; |
8 | use StatusValue; |
9 | use Wikimedia\Assert\Assert; |
10 | use Wikimedia\ObjectCache\WANObjectCache; |
11 | use Wikimedia\Stats\IBufferingStatsdDataFactory; |
12 | |
13 | /** |
14 | * Get image recommendation data from cache if possible; fall back to service provider otherwise. |
15 | * |
16 | * Used as a drop-in replacement for the uncached ServiceImageRecommendationProvider. The static |
17 | * method is called in CacheDecorator.php when a TaskSet includes ImageRecommendationTaskType objects. |
18 | */ |
19 | class CacheBackedImageRecommendationProvider implements ImageRecommendationProvider { |
20 | |
21 | /** @var WANObjectCache */ |
22 | private $cache; |
23 | |
24 | /** @var ImageRecommendationProvider */ |
25 | private $imageRecommendationProvider; |
26 | |
27 | /** @var IBufferingStatsdDataFactory */ |
28 | private $statsdDataFactory; |
29 | |
30 | /** |
31 | * @param WANObjectCache $cache |
32 | * @param ImageRecommendationProvider $imageRecommendationProvider |
33 | * @param IBufferingStatsdDataFactory $statsdDataFactory |
34 | */ |
35 | public function __construct( |
36 | WANObjectCache $cache, |
37 | ImageRecommendationProvider $imageRecommendationProvider, |
38 | IBufferingStatsdDataFactory $statsdDataFactory |
39 | ) { |
40 | $this->cache = $cache; |
41 | $this->imageRecommendationProvider = $imageRecommendationProvider; |
42 | $this->statsdDataFactory = $statsdDataFactory; |
43 | } |
44 | |
45 | /** @inheritDoc */ |
46 | public function get( LinkTarget $title, TaskType $taskType ) { |
47 | Assert::parameterType( ImageRecommendationBaseTaskType::class, $taskType, '$taskType' ); |
48 | return self::getWithSetCallback( |
49 | $this->cache, |
50 | $this->imageRecommendationProvider, |
51 | $taskType, |
52 | $title, |
53 | __METHOD__, |
54 | $this->statsdDataFactory |
55 | ); |
56 | } |
57 | |
58 | /** |
59 | * @param WANObjectCache $cache |
60 | * @param ImageRecommendationProvider $imageRecommendationProvider |
61 | * @param TaskType $taskType |
62 | * @param LinkTarget $title |
63 | * @param string $fname The context in which this method is called. Used for instrumenting cache misses. |
64 | * @param IBufferingStatsdDataFactory $statsdDataFactory |
65 | * @return false|mixed |
66 | */ |
67 | public static function getWithSetCallback( |
68 | WANObjectCache $cache, |
69 | ImageRecommendationProvider $imageRecommendationProvider, |
70 | TaskType $taskType, |
71 | LinkTarget $title, |
72 | string $fname, |
73 | IBufferingStatsdDataFactory $statsdDataFactory |
74 | ) { |
75 | return $cache->getWithSetCallback( |
76 | self::makeKey( $cache, $taskType->getId(), $title->getDBkey() ), |
77 | // The recommendation won't change, but other metadata might and caching for longer might be |
78 | // problematic if e.g. the image got vandalized. |
79 | $cache::TTL_MINUTE * 5, |
80 | static function ( $oldValue, &$ttl ) use ( |
81 | $title, $taskType, $imageRecommendationProvider, $cache, $fname, $statsdDataFactory |
82 | ) { |
83 | // This is a cache miss. That is expected when TaskSetListener->run calls the method, because we're |
84 | // warming the cache. We want to instrument cache misses when we get here from the ::get method, |
85 | // because that's called in BeforePageDisplay where we expect to have a cached result. |
86 | if ( $fname === __CLASS__ . '::get' ) { |
87 | $statsdDataFactory->increment( 'GrowthExperiments.CacheBackedImageRecommendationProvider.miss' ); |
88 | } |
89 | |
90 | $response = $imageRecommendationProvider->get( $title, $taskType ); |
91 | if ( $response instanceof StatusValue ) { |
92 | $ttl = $cache::TTL_UNCACHEABLE; |
93 | } |
94 | return $response; |
95 | } |
96 | ); |
97 | } |
98 | |
99 | /** |
100 | * @param WANObjectCache $cache |
101 | * @param string $taskTypeId |
102 | * @param string $dbKey |
103 | * @return string |
104 | */ |
105 | public static function makeKey( WANObjectCache $cache, string $taskTypeId, string $dbKey ): string { |
106 | return $cache->makeKey( 'GrowthExperiments', 'Recommendations', $taskTypeId, $dbKey ); |
107 | } |
108 | } |