Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
WikifunctionsClientFanOutQueueJob
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 2
12
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 run
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
6
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\JobQueue\GenericParameterJob;
13use MediaWiki\JobQueue\Job;
14use MediaWiki\JobQueue\JobQueueGroupFactory;
15use MediaWiki\JobQueue\JobSpecification;
16use MediaWiki\Logger\LoggerFactory;
17use MediaWiki\MediaWikiServices;
18use Psr\Log\LoggerInterface;
19
20/**
21 * Asynchronous job run on the repo wiki to schedule local updates to client wikis
22 */
23class WikifunctionsClientFanOutQueueJob extends Job implements GenericParameterJob {
24
25    private LoggerInterface $logger;
26    private JobQueueGroupFactory $jobQueueGroupFactory;
27
28    public function __construct( array $params ) {
29        // This job, triggered from RecentChanges activity on the repo wiki, takes the edit and fans it out to each
30        // relevant client wiki to process locally.
31
32        parent::__construct( 'wikifunctionsClientFanOutQueue', $params );
33
34        $this->logger = LoggerFactory::getInstance( 'WikiLambda' );
35        $this->jobQueueGroupFactory = MediaWikiServices::getInstance()->getJobQueueGroupFactory();
36
37        $this->params = $params;
38
39        $this->logger->debug(
40            __CLASS__ . ' created for {targetZObject} — {params}',
41            [
42                'targetZObject' => $params['target'],
43                'params' => var_export( $params, true ),
44            ]
45        );
46    }
47
48    /**
49     * @return bool
50     */
51    public function run() {
52        $config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'WikiLambda' );
53
54        $this->logger->debug(
55            __CLASS__ . ' initiated for {targetZObject}',
56            [
57                'targetZObject' => $this->params['target']
58            ]
59        );
60
61        // TODO (T385630): Instead of a single job for each client wiki to cover all pages, we could have yet another
62        // layer of jobs which are specific to each page. This is what Wikibase does. (But then the repo wiki needs to
63        // know which remote pages use each Function, which is currently only held locally on client wikis.)
64
65        // Note: We're using the JobSpecification static, serialisable class as we're handing off to
66        // MW instances, potentially running different versions of the code (unlike locally).
67        $jobSpec = new JobSpecification( 'wikifunctionsRecentChangesInsert', [
68            // The name of the Object that changed in the form of a string, e.g. 'Z12345'
69            'target' => $this->params['target'],
70            // The timestamp of the edit, e.g. '20210101000000'
71            'timestamp' => $this->params['timestamp'],
72            // The edit summary of the edit on the repo wiki
73            'summary' => $this->params['summary'],
74            // Structured data about the edit
75            'data' => $this->params['data'],
76            // The user ID of the user that made the edit on the repo wiki
77            'user' => $this->params['user'],
78            // Whether the user that made the edit on the repo wiki did so as a bot
79            'bot' => $this->params['bot'],
80        ] );
81
82        // Get client wikis
83        $clientWikis = $config->get( 'WikiLambdaClientWikis' );
84
85        $this->logger->debug(
86            __CLASS__ . ' has a list of wikis: {clientWikis}',
87            [
88                'clientWikis' => var_export( $clientWikis, true )
89            ]
90        );
91
92        // TODO (T385621): Filter down to relevant client wikis that subscribe to this Function
93        // This will need (a) a table on the repo wiki (or x3/etc.?) to store what client wikis are subscribed
94        // to what Functions, and (b) update jobs to update that table when a Function is used or dropped
95
96        // For each client wiki, create a job and push it to that wiki's job queue
97        // NOTE: Like Wikibase, this requires all client wikis to be DB-writable in the same cluster as the repo wiki.
98        foreach ( $clientWikis as $clientWiki ) {
99            $this->logger->debug(
100                __CLASS__ . ' despatching to {targetWiki} for {item} edit {revision}',
101                [
102                    'targetWiki' => $clientWiki,
103                    'item' => $this->params['target'],
104                    'revision' => $this->params['revision']
105                ]
106            );
107            $jobQueueGroup = $this->jobQueueGroupFactory->makeJobQueueGroup( $clientWiki );
108            $jobQueueGroup->lazyPush( $jobSpec );
109        }
110
111        return true;
112    }
113}