1, 'usleep' => 100, 'pi' => 3.141569 ), * array( 'removeDuplicates' => 1 ), * Title::makeTitle( NS_SPECIAL, 'nullity' ) * ); * JobQueueGroup::singleton()->push( $job ) * @endcode * * @ingroup JobQueue * @since 1.23 */ class JobSpecification implements IJobSpecification { /** @var string */ protected $type; /** @var array Array of job parameters or false if none */ protected $params; /** @var Title */ protected $title; /** @var array */ protected $opts; /** * @param string $type * @param array $params Map of key/values * @param array $opts Map of key/values; includes 'removeDuplicates' * @param Title $title Optional descriptive title */ public function __construct( $type, array $params, array $opts = [], Title $title = null ) { $this->validateParams( $params ); $this->validateParams( $opts ); $this->type = $type; $this->params = $params; $this->title = $title ?: Title::makeTitle( NS_SPECIAL, 'Badtitle/' . static::class ); $this->opts = $opts; } /** * @param array $params */ protected function validateParams( array $params ) { foreach ( $params as $p => $v ) { if ( is_array( $v ) ) { $this->validateParams( $v ); } elseif ( !is_scalar( $v ) && $v !== null ) { throw new UnexpectedValueException( "Job parameter $p is not JSON serializable." ); } } } public function getType() { return $this->type; } public function getTitle() { return $this->title; } public function getParams() { return $this->params; } public function getReleaseTimestamp() { return isset( $this->params['jobReleaseTimestamp'] ) ? wfTimestampOrNull( TS_UNIX, $this->params['jobReleaseTimestamp'] ) : null; } public function ignoreDuplicates() { return !empty( $this->opts['removeDuplicates'] ); } public function getDeduplicationInfo() { $info = [ 'type' => $this->getType(), 'namespace' => $this->getTitle()->getNamespace(), 'title' => $this->getTitle()->getDBkey(), 'params' => $this->getParams() ]; if ( is_array( $info['params'] ) ) { // Identical jobs with different "root" jobs should count as duplicates unset( $info['params']['rootJobSignature'] ); unset( $info['params']['rootJobTimestamp'] ); // Likewise for jobs with different delay times unset( $info['params']['jobReleaseTimestamp'] ); } return $info; } public function getRootJobParams() { return [ 'rootJobSignature' => isset( $this->params['rootJobSignature'] ) ? $this->params['rootJobSignature'] : null, 'rootJobTimestamp' => isset( $this->params['rootJobTimestamp'] ) ? $this->params['rootJobTimestamp'] : null ]; } public function hasRootJobParams() { return isset( $this->params['rootJobSignature'] ) && isset( $this->params['rootJobTimestamp'] ); } public function isRootJob() { return $this->hasRootJobParams() && !empty( $this->params['rootJobIsSelf'] ); } /** * @return array Field/value map that can immediately be serialized * @since 1.25 */ public function toSerializableArray() { return [ 'type' => $this->type, 'params' => $this->params, 'opts' => $this->opts, 'title' => [ 'ns' => $this->title->getNamespace(), 'key' => $this->title->getDBkey() ] ]; } /** * @param array $map Field/value map * @return JobSpecification * @since 1.25 */ public static function newFromArray( array $map ) { $title = Title::makeTitle( $map['title']['ns'], $map['title']['key'] ); return new self( $map['type'], $map['params'], $map['opts'], $title ); } }