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.
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.
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
21 * @defgroup JobQueue JobQueue
22 * @author Aaron Schulz
26 * Class to handle enqueueing and running of background jobs
31 abstract class JobQueue
{
32 protected $wiki; // string; wiki ID
33 protected $type; // string; job type
35 const QoS_Atomic
= 1; // integer; "all-or-nothing" job insertions
38 * @param $params array
40 protected function __construct( array $params ) {
41 $this->wiki
= $params['wiki'];
42 $this->type
= $params['type'];
46 * Get a job queue object of the specified type.
48 * class : what job class to use (determines job type)
49 * wiki : wiki ID of the wiki the jobs are for (defaults to current wiki)
50 * type : The name of the job types this queue handles
52 * @param $params array
56 final public static function factory( array $params ) {
57 $class = $params['class'];
58 if ( !MWInit
::classExists( $class ) ) {
59 throw new MWException( "Invalid job queue class '$class'." );
61 $obj = new $class( $params );
62 if ( !( $obj instanceof self
) ) {
63 throw new MWException( "Class '$class' is not a " . __CLASS__
. " class." );
69 * @return string Wiki ID
71 final public function getWiki() {
76 * @return string Job type that this queue handles
78 final public function getType() {
83 * @return bool Quickly check if the queue is empty
85 final public function isEmpty() {
86 wfProfileIn( __METHOD__
);
87 $res = $this->doIsEmpty();
88 wfProfileOut( __METHOD__
);
93 * @see JobQueue::isEmpty()
96 abstract protected function doIsEmpty();
99 * Push a batch of jobs into the queue
101 * @param $jobs array List of Jobs
102 * @param $flags integer Bitfield (supports JobQueue::QoS_Atomic)
105 final public function batchPush( array $jobs, $flags = 0 ) {
106 foreach ( $jobs as $job ) {
107 if ( $job->getType() !== $this->type
) {
108 throw new MWException( "Got '{$job->getType()}' job; expected '{$this->type}'." );
111 wfProfileIn( __METHOD__
);
112 $ok = $this->doBatchPush( $jobs, $flags );
114 wfIncrStats( 'job-insert', count( $jobs ) );
116 wfProfileOut( __METHOD__
);
121 * @see JobQueue::batchPush()
124 abstract protected function doBatchPush( array $jobs, $flags );
127 * Pop a job off of the queue
129 * @return Job|bool Returns false on failure
131 final public function pop() {
132 wfProfileIn( __METHOD__
);
133 $job = $this->doPop();
135 wfIncrStats( 'job-pop' );
137 wfProfileOut( __METHOD__
);
142 * @see JobQueue::pop()
145 abstract protected function doPop();
148 * Acknowledge that a job was completed
153 final public function ack( Job
$job ) {
154 if ( $job->getType() !== $this->type
) {
155 throw new MWException( "Got '{$job->getType()}' job; expected '{$this->type}'." );
157 wfProfileIn( __METHOD__
);
158 $ok = $this->doAck( $job );
159 wfProfileOut( __METHOD__
);
164 * @see JobQueue::ack()
167 abstract protected function doAck( Job
$job );
170 * Wait for any slaves or backup servers to catch up
174 final public function waitForBackups() {
175 wfProfileIn( __METHOD__
);
176 $this->doWaitForBackups();
177 wfProfileOut( __METHOD__
);
181 * @see JobQueue::waitForBackups()
184 protected function doWaitForBackups() {}