Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
48 / 48
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
CacheAbstractContentFragmentJob
100.00% covered (success)
100.00%
48 / 48
100.00% covered (success)
100.00%
5 / 5
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 run
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
2
 ignoreDuplicates
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDeduplicationInfo
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 allowRetries
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * @file
5 * @ingroup Extensions
6 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
7 * @license MIT
8 */
9
10namespace MediaWiki\Extension\WikiLambda\Jobs;
11
12use MediaWiki\Config\Config;
13use MediaWiki\Extension\WikiLambda\AbstractContent\AbstractWikiRequest;
14use MediaWiki\Extension\WikiLambda\WikiLambdaServices;
15use MediaWiki\Http\HttpRequestFactory;
16use MediaWiki\JobQueue\GenericParameterJob;
17use MediaWiki\JobQueue\Job;
18use MediaWiki\Logger\LoggerFactory;
19use MediaWiki\MediaWikiServices;
20use Psr\Log\LoggerInterface;
21
22/**
23 * Asynchronous job run on Abstract Wiki to refresh an Abstract Content
24 * fragment which is only available in the cache in an older version.
25 * This job requests Wikifunctions to re-render the fragment via the
26 * wikilambda_function_call Action API and updates the cache key with
27 * and without today's date.
28 */
29class CacheAbstractContentFragmentJob extends Job implements GenericParameterJob {
30
31    private Config $config;
32    private HttpRequestFactory $httpRequestFactory;
33    private AbstractWikiRequest $abstractWikiRequest;
34    private LoggerInterface $logger;
35
36    /**
37     * @inheritDoc
38     */
39    public function __construct( array $params ) {
40        parent::__construct( 'cacheAbstractContentFragment', $params );
41
42        $this->config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'WikiLambda' );
43        $this->logger = LoggerFactory::getInstance( 'WikiLambdaAbstract' );
44
45        $this->abstractWikiRequest = WikiLambdaServices::getAbstractWikiRequest();
46
47        $this->logger->debug(
48            __CLASS__ . ' created',
49            [
50                'qid' => $params['qid'],
51                'language' => $params['language'],
52                'date' => $params['date']
53            ]
54        );
55    }
56
57    /**
58     * Asynchronous job to re-generate and rfresh the rendered fragment in the cache.
59     * * Makes a remote call to Wikifunctions wikilambda_function_call to evaluate a fragment fragment
60     * * Sanitizes the HTML response.
61     * * Caches resulting fragment under fresh and stale cache keys.
62     *
63     * @return bool
64     */
65    public function run() {
66        $functionCall = $this->params['functionCall'];
67        $cacheKeyFresh = $this->params['cacheKeyFresh'];
68        $cacheKeyStale = $this->params['cacheKeyStale'];
69
70        $this->logger->debug(
71            __CLASS__ . ' initiated for qid:{qid} language:{language} and date:{date} ',
72            [
73                'qid' => $this->params['qid'],
74                'language' => $this->params['language'],
75                'date' => $this->params['date']
76            ]
77        );
78
79        $cachedValue = $this->abstractWikiRequest->generateSafeFragment(
80            $functionCall,
81            $cacheKeyFresh,
82            $cacheKeyStale
83        );
84
85        $this->logger->debug(
86            __CLASS__ . ' refreshed {status} cached fragment for qid:{qid} language:{language} and date:{date} ',
87            [
88                'status' => $cachedValue[ 'success' ] ? 'successful' : 'failed',
89                'qid' => $this->params['qid'],
90                'language' => $this->params['language'],
91                'date' => $this->params['date']
92            ]
93        );
94
95        // Return true even if cachedValue was failed; no job retries
96        return true;
97    }
98
99    /**
100     * @inheritDoc
101     */
102    public function ignoreDuplicates() {
103        // We've carefully chosen the parameters so this Job is shared across multiple uses, so don't run it
104        // in parallel and have MediaWiki de-duplicate requests.
105        return true;
106    }
107
108    /**
109     * @inheritDoc
110     */
111    public function getDeduplicationInfo() {
112        $info = parent::getDeduplicationInfo();
113        // When deduplicating, only keep fragment-defining parameters
114        $info[ 'params' ] = [
115            'qid' => $this->params['qid'],
116            'language' => $this->params['language'],
117            'date' => $this->params['date'],
118            'functionCall' => $this->params['functionCall'],
119        ];
120
121        return $info;
122    }
123
124    /**
125     * @inheritDoc
126     */
127    public function allowRetries() {
128        return false;
129    }
130}