]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/jobqueue/JobSpecification.php
MediaWiki 1.30.2-scripts2
[autoinstalls/mediawiki.git] / includes / jobqueue / JobSpecification.php
1 <?php
2 /**
3  * Job queue task description base code.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  * http://www.gnu.org/copyleft/gpl.html
19  *
20  * @file
21  * @ingroup JobQueue
22  */
23
24 /**
25  * Job queue task description interface
26  *
27  * @ingroup JobQueue
28  * @since 1.23
29  */
30 interface IJobSpecification {
31         /**
32          * @return string Job type
33          */
34         public function getType();
35
36         /**
37          * @return array
38          */
39         public function getParams();
40
41         /**
42          * @return int|null UNIX timestamp to delay running this job until, otherwise null
43          */
44         public function getReleaseTimestamp();
45
46         /**
47          * @return bool Whether only one of each identical set of jobs should be run
48          */
49         public function ignoreDuplicates();
50
51         /**
52          * Subclasses may need to override this to make duplication detection work.
53          * The resulting map conveys everything that makes the job unique. This is
54          * only checked if ignoreDuplicates() returns true, meaning that duplicate
55          * jobs are supposed to be ignored.
56          *
57          * @return array Map of key/values
58          */
59         public function getDeduplicationInfo();
60
61         /**
62          * @see JobQueue::deduplicateRootJob()
63          * @return array
64          * @since 1.26
65          */
66         public function getRootJobParams();
67
68         /**
69          * @see JobQueue::deduplicateRootJob()
70          * @return bool
71          * @since 1.22
72          */
73         public function hasRootJobParams();
74
75         /**
76          * @see JobQueue::deduplicateRootJob()
77          * @return bool Whether this is job is a root job
78          */
79         public function isRootJob();
80
81         /**
82          * @return Title Descriptive title (this can simply be informative)
83          */
84         public function getTitle();
85 }
86
87 /**
88  * Job queue task description base code
89  *
90  * Example usage:
91  * @code
92  * $job = new JobSpecification(
93  *              'null',
94  *              array( 'lives' => 1, 'usleep' => 100, 'pi' => 3.141569 ),
95  *              array( 'removeDuplicates' => 1 ),
96  *              Title::makeTitle( NS_SPECIAL, 'nullity' )
97  * );
98  * JobQueueGroup::singleton()->push( $job )
99  * @endcode
100  *
101  * @ingroup JobQueue
102  * @since 1.23
103  */
104 class JobSpecification implements IJobSpecification {
105         /** @var string */
106         protected $type;
107
108         /** @var array Array of job parameters or false if none */
109         protected $params;
110
111         /** @var Title */
112         protected $title;
113
114         /** @var array */
115         protected $opts;
116
117         /**
118          * @param string $type
119          * @param array $params Map of key/values
120          * @param array $opts Map of key/values; includes 'removeDuplicates'
121          * @param Title $title Optional descriptive title
122          */
123         public function __construct(
124                 $type, array $params, array $opts = [], Title $title = null
125         ) {
126                 $this->validateParams( $params );
127                 $this->validateParams( $opts );
128
129                 $this->type = $type;
130                 $this->params = $params;
131                 $this->title = $title ?: Title::makeTitle( NS_SPECIAL, 'Badtitle/' . static::class );
132                 $this->opts = $opts;
133         }
134
135         /**
136          * @param array $params
137          */
138         protected function validateParams( array $params ) {
139                 foreach ( $params as $p => $v ) {
140                         if ( is_array( $v ) ) {
141                                 $this->validateParams( $v );
142                         } elseif ( !is_scalar( $v ) && $v !== null ) {
143                                 throw new UnexpectedValueException( "Job parameter $p is not JSON serializable." );
144                         }
145                 }
146         }
147
148         public function getType() {
149                 return $this->type;
150         }
151
152         public function getTitle() {
153                 return $this->title;
154         }
155
156         public function getParams() {
157                 return $this->params;
158         }
159
160         public function getReleaseTimestamp() {
161                 return isset( $this->params['jobReleaseTimestamp'] )
162                         ? wfTimestampOrNull( TS_UNIX, $this->params['jobReleaseTimestamp'] )
163                         : null;
164         }
165
166         public function ignoreDuplicates() {
167                 return !empty( $this->opts['removeDuplicates'] );
168         }
169
170         public function getDeduplicationInfo() {
171                 $info = [
172                         'type' => $this->getType(),
173                         'namespace' => $this->getTitle()->getNamespace(),
174                         'title' => $this->getTitle()->getDBkey(),
175                         'params' => $this->getParams()
176                 ];
177                 if ( is_array( $info['params'] ) ) {
178                         // Identical jobs with different "root" jobs should count as duplicates
179                         unset( $info['params']['rootJobSignature'] );
180                         unset( $info['params']['rootJobTimestamp'] );
181                         // Likewise for jobs with different delay times
182                         unset( $info['params']['jobReleaseTimestamp'] );
183                 }
184
185                 return $info;
186         }
187
188         public function getRootJobParams() {
189                 return [
190                         'rootJobSignature' => isset( $this->params['rootJobSignature'] )
191                                 ? $this->params['rootJobSignature']
192                                 : null,
193                         'rootJobTimestamp' => isset( $this->params['rootJobTimestamp'] )
194                                 ? $this->params['rootJobTimestamp']
195                                 : null
196                 ];
197         }
198
199         public function hasRootJobParams() {
200                 return isset( $this->params['rootJobSignature'] )
201                         && isset( $this->params['rootJobTimestamp'] );
202         }
203
204         public function isRootJob() {
205                 return $this->hasRootJobParams() && !empty( $this->params['rootJobIsSelf'] );
206         }
207
208         /**
209          * @return array Field/value map that can immediately be serialized
210          * @since 1.25
211          */
212         public function toSerializableArray() {
213                 return [
214                         'type'   => $this->type,
215                         'params' => $this->params,
216                         'opts'   => $this->opts,
217                         'title'  => [
218                                 'ns'  => $this->title->getNamespace(),
219                                 'key' => $this->title->getDBkey()
220                         ]
221                 ];
222         }
223
224         /**
225          * @param array $map Field/value map
226          * @return JobSpecification
227          * @since 1.25
228          */
229         public static function newFromArray( array $map ) {
230                 $title = Title::makeTitle( $map['title']['ns'], $map['title']['key'] );
231
232                 return new self( $map['type'], $map['params'], $map['opts'], $title );
233         }
234 }