Merge "clone is not a function"
[lhc/web/wiklou.git] / includes / jobqueue / JobQueueGroup.php
index fdf7b87..5bd1cc9 100644 (file)
@@ -28,7 +28,7 @@
  * @since 1.21
  */
 class JobQueueGroup {
-       /** @var array */
+       /** @var JobQueueGroup[] */
        protected static $instances = array();
 
        /** @var ProcessCacheLRU */
@@ -40,6 +40,9 @@ class JobQueueGroup {
        /** @var array Map of (bucket => (queue => JobQueue, types => list of types) */
        protected $coalescedQueues;
 
+       /** @var Job[] */
+       protected $bufferedJobs = array();
+
        const TYPE_DEFAULT = 1; // integer; jobs popped by default
        const TYPE_ANY = 2; // integer; any job
 
@@ -100,13 +103,13 @@ class JobQueueGroup {
        }
 
        /**
-        * Insert jobs into the respective queues of with the belong.
+        * Insert jobs into the respective queues of which they belong
         *
         * This inserts the jobs into the queue specified by $wgJobTypeConf
         * and updates the aggregate job queue information cache as needed.
         *
-        * @param Job|Job[] $jobs A single Job or a list of Jobs
-        * @throws MWException
+        * @param IJobSpecification|IJobSpecification[] $jobs A single Job or a list of Jobs
+        * @throws InvalidArgumentException
         * @return void
         */
        public function push( $jobs ) {
@@ -115,13 +118,11 @@ class JobQueueGroup {
                        return;
                }
 
+               $this->assertValidJobs( $jobs );
+
                $jobsByType = array(); // (job type => list of jobs)
                foreach ( $jobs as $job ) {
-                       if ( $job instanceof IJobSpecification ) {
-                               $jobsByType[$job->getType()][] = $job;
-                       } else {
-                               throw new MWException( "Attempted to push a non-Job object into a queue." );
-                       }
+                       $jobsByType[$job->getType()][] = $job;
                }
 
                foreach ( $jobsByType as $type => $jobs ) {
@@ -136,6 +137,42 @@ class JobQueueGroup {
                }
        }
 
+       /**
+        * Buffer jobs for insertion via push() or call it now if in CLI mode
+        *
+        * Note that MediaWiki::restInPeace() calls pushLazyJobs()
+        *
+        * @param IJobSpecification|IJobSpecification[] $jobs A single Job or a list of Jobs
+        * @return void
+        * @since 1.26
+        */
+       public function lazyPush( $jobs ) {
+               if ( PHP_SAPI === 'cli' ) {
+                       $this->push( $jobs );
+                       return;
+               }
+
+               $jobs = is_array( $jobs ) ? $jobs : array( $jobs );
+
+               // Throw errors now instead of on push(), when other jobs may be buffered
+               $this->assertValidJobs( $jobs );
+
+               $this->bufferedJobs = array_merge( $this->bufferedJobs, $jobs );
+       }
+
+       /**
+        * Push all jobs buffered via lazyPush() into their respective queues
+        *
+        * @return void
+        * @since 1.26
+        */
+       public static function pushLazyJobs() {
+               foreach ( self::$instances as $group ) {
+                       $group->push( $group->bufferedJobs );
+                       $group->bufferedJobs = array();
+               }
+       }
+
        /**
         * Pop a job off one of the job queues
         *
@@ -188,10 +225,10 @@ class JobQueueGroup {
         * Acknowledge that a job was completed
         *
         * @param Job $job
-        * @return bool
+        * @return void
         */
        public function ack( Job $job ) {
-               return $this->get( $job->getType() )->ack( $job );
+               $this->get( $job->getType() )->ack( $job );
        }
 
        /**
@@ -211,7 +248,6 @@ class JobQueueGroup {
         * This does nothing for certain queue classes.
         *
         * @return void
-        * @throws MWException
         */
        public function waitForBackups() {
                global $wgJobTypeConf;
@@ -364,4 +400,24 @@ class JobQueueGroup {
                        }
                }
        }
+
+       /**
+        * @param array $jobs
+        * @throws InvalidArgumentException
+        */
+       private function assertValidJobs( array $jobs ) {
+               foreach ( $jobs as $job ) { // sanity checks
+                       if ( !( $job instanceof IJobSpecification ) ) {
+                               throw new InvalidArgumentException( "Expected IJobSpecification objects" );
+                       }
+               }
+       }
+
+       function __destruct() {
+               $n = count( $this->bufferedJobs );
+               if ( $n > 0 ) {
+                       $type = implode( ', ', array_unique( array_map( 'get_class', $this->bufferedJobs ) ) );
+                       trigger_error( __METHOD__ . ": $n buffered job(s) of type(s) $type never inserted." );
+               }
+       }
 }