]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/jobqueue/JobQueueMemory.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / jobqueue / JobQueueMemory.php
1 <?php
2 /**
3  * PHP memory-backed job queue 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  */
22
23 /**
24  * Class to handle job queues stored in PHP memory for testing
25  *
26  * JobQueueGroup does not remember every queue instance, so statically track it here
27  *
28  * @ingroup JobQueue
29  * @since 1.27
30  */
31 class JobQueueMemory extends JobQueue {
32         /** @var array[] */
33         protected static $data = [];
34
35         /**
36          * @see JobQueue::doBatchPush
37          *
38          * @param IJobSpecification[] $jobs
39          * @param int $flags
40          */
41         protected function doBatchPush( array $jobs, $flags ) {
42                 $unclaimed =& $this->getQueueData( 'unclaimed', [] );
43
44                 foreach ( $jobs as $job ) {
45                         if ( $job->ignoreDuplicates() ) {
46                                 $sha1 = Wikimedia\base_convert(
47                                         sha1( serialize( $job->getDeduplicationInfo() ) ),
48                                         16, 36, 31
49                                 );
50                                 if ( !isset( $unclaimed[$sha1] ) ) {
51                                         $unclaimed[$sha1] = $job;
52                                 }
53                         } else {
54                                 $unclaimed[] = $job;
55                         }
56                 }
57         }
58
59         /**
60          * @see JobQueue::supportedOrders
61          *
62          * @return string[]
63          */
64         protected function supportedOrders() {
65                 return [ 'random', 'timestamp', 'fifo' ];
66         }
67
68         /**
69          * @see JobQueue::optimalOrder
70          *
71          * @return string
72          */
73         protected function optimalOrder() {
74                 return 'fifo';
75         }
76
77         /**
78          * @see JobQueue::doIsEmpty
79          *
80          * @return bool
81          */
82         protected function doIsEmpty() {
83                 return ( $this->doGetSize() == 0 );
84         }
85
86         /**
87          * @see JobQueue::doGetSize
88          *
89          * @return int
90          */
91         protected function doGetSize() {
92                 $unclaimed = $this->getQueueData( 'unclaimed' );
93
94                 return $unclaimed ? count( $unclaimed ) : 0;
95         }
96
97         /**
98          * @see JobQueue::doGetAcquiredCount
99          *
100          * @return int
101          */
102         protected function doGetAcquiredCount() {
103                 $claimed = $this->getQueueData( 'claimed' );
104
105                 return $claimed ? count( $claimed ) : 0;
106         }
107
108         /**
109          * @see JobQueue::doPop
110          *
111          * @return Job|bool
112          */
113         protected function doPop() {
114                 if ( $this->doGetSize() == 0 ) {
115                         return false;
116                 }
117
118                 $unclaimed =& $this->getQueueData( 'unclaimed' );
119                 $claimed =& $this->getQueueData( 'claimed', [] );
120
121                 if ( $this->order === 'random' ) {
122                         $key = array_rand( $unclaimed );
123                 } else {
124                         reset( $unclaimed );
125                         $key = key( $unclaimed );
126                 }
127
128                 $spec = $unclaimed[$key];
129                 unset( $unclaimed[$key] );
130                 $claimed[] = $spec;
131
132                 $job = $this->jobFromSpecInternal( $spec );
133
134                 end( $claimed );
135                 $job->metadata['claimId'] = key( $claimed );
136
137                 return $job;
138         }
139
140         /**
141          * @see JobQueue::doAck
142          *
143          * @param Job $job
144          */
145         protected function doAck( Job $job ) {
146                 if ( $this->getAcquiredCount() == 0 ) {
147                         return;
148                 }
149
150                 $claimed =& $this->getQueueData( 'claimed' );
151                 unset( $claimed[$job->metadata['claimId']] );
152         }
153
154         /**
155          * @see JobQueue::doDelete
156          */
157         protected function doDelete() {
158                 if ( isset( self::$data[$this->type][$this->wiki] ) ) {
159                         unset( self::$data[$this->type][$this->wiki] );
160                         if ( !self::$data[$this->type] ) {
161                                 unset( self::$data[$this->type] );
162                         }
163                 }
164         }
165
166         /**
167          * @see JobQueue::getAllQueuedJobs
168          *
169          * @return Iterator of Job objects.
170          */
171         public function getAllQueuedJobs() {
172                 $unclaimed = $this->getQueueData( 'unclaimed' );
173                 if ( !$unclaimed ) {
174                         return new ArrayIterator( [] );
175                 }
176
177                 return new MappedIterator(
178                         $unclaimed,
179                         function ( $value ) {
180                                 return $this->jobFromSpecInternal( $value );
181                         }
182                 );
183         }
184
185         /**
186          * @see JobQueue::getAllAcquiredJobs
187          *
188          * @return Iterator of Job objects.
189          */
190         public function getAllAcquiredJobs() {
191                 $claimed = $this->getQueueData( 'claimed' );
192                 if ( !$claimed ) {
193                         return new ArrayIterator( [] );
194                 }
195
196                 return new MappedIterator(
197                         $claimed,
198                         function ( $value ) {
199                                 return $this->jobFromSpecInternal( $value );
200                         }
201                 );
202         }
203
204         /**
205          * @param IJobSpecification $spec
206          *
207          * @return Job
208          */
209         public function jobFromSpecInternal( IJobSpecification $spec ) {
210                 return Job::factory( $spec->getType(), $spec->getTitle(), $spec->getParams() );
211         }
212
213         /**
214          * @param string $field
215          * @param mixed $init
216          *
217          * @return mixed
218          */
219         private function &getQueueData( $field, $init = null ) {
220                 if ( !isset( self::$data[$this->type][$this->wiki][$field] ) ) {
221                         if ( $init !== null ) {
222                                 self::$data[$this->type][$this->wiki][$field] = $init;
223                         } else {
224                                 return $init;
225                         }
226                 }
227
228                 return self::$data[$this->type][$this->wiki][$field];
229         }
230 }