%PDF- %PDF-
Direktori : /home2/vacivi36/intranet.vacivitta.com.br/protected/vendor/yiisoft/yii2-queue/src/ |
Current File : //home2/vacivi36/intranet.vacivitta.com.br/protected/vendor/yiisoft/yii2-queue/src/Queue.php |
<?php /** * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license https://www.yiiframework.com/license/ */ namespace yii\queue; use Yii; use yii\base\Component; use yii\base\InvalidArgumentException; use yii\base\InvalidConfigException; use yii\di\Instance; use yii\helpers\VarDumper; use yii\queue\serializers\PhpSerializer; use yii\queue\serializers\SerializerInterface; /** * Base Queue. * * @property null|int $workerPid * @since 2.0.2 * * @author Roman Zhuravlev <zhuravljov@gmail.com> */ abstract class Queue extends Component { /** * @event PushEvent */ const EVENT_BEFORE_PUSH = 'beforePush'; /** * @event PushEvent */ const EVENT_AFTER_PUSH = 'afterPush'; /** * @event ExecEvent */ const EVENT_BEFORE_EXEC = 'beforeExec'; /** * @event ExecEvent */ const EVENT_AFTER_EXEC = 'afterExec'; /** * @event ExecEvent */ const EVENT_AFTER_ERROR = 'afterError'; /** * @see Queue::isWaiting() */ const STATUS_WAITING = 1; /** * @see Queue::isReserved() */ const STATUS_RESERVED = 2; /** * @see Queue::isDone() */ const STATUS_DONE = 3; /** * @var bool whether to enable strict job type control. * Note that in order to enable type control, a pushing job must be [[JobInterface]] instance. * @since 2.0.1 */ public $strictJobType = true; /** * @var SerializerInterface|array */ public $serializer = PhpSerializer::class; /** * @var int default time to reserve a job */ public $ttr = 300; /** * @var int default attempt count */ public $attempts = 1; private $pushTtr; private $pushDelay; private $pushPriority; /** * @inheritdoc */ public function init() { parent::init(); $this->serializer = Instance::ensure($this->serializer, SerializerInterface::class); if (!is_numeric($this->ttr)) { throw new InvalidConfigException('Default TTR must be integer.'); } $this->ttr = (int) $this->ttr; if ($this->ttr <= 0) { throw new InvalidConfigException('Default TTR must be greater that zero.'); } if (!is_numeric($this->attempts)) { throw new InvalidConfigException('Default attempts count must be integer.'); } $this->attempts = (int) $this->attempts; if ($this->attempts <= 0) { throw new InvalidConfigException('Default attempts count must be greater that zero.'); } } /** * Sets TTR for job execute. * * @param int|mixed $value * @return $this */ public function ttr($value) { $this->pushTtr = $value; return $this; } /** * Sets delay for later execute. * * @param int|mixed $value * @return $this */ public function delay($value) { $this->pushDelay = $value; return $this; } /** * Sets job priority. * * @param mixed $value * @return $this */ public function priority($value) { $this->pushPriority = $value; return $this; } /** * Pushes job into queue. * * @param JobInterface|mixed $job * @return string|null id of a job message */ public function push($job) { $event = new PushEvent([ 'job' => $job, 'ttr' => $this->pushTtr ?: ( $job instanceof RetryableJobInterface ? $job->getTtr() : $this->ttr ), 'delay' => $this->pushDelay ?: 0, 'priority' => $this->pushPriority, ]); $this->pushTtr = null; $this->pushDelay = null; $this->pushPriority = null; $this->trigger(self::EVENT_BEFORE_PUSH, $event); if ($event->handled) { return null; } if ($this->strictJobType && !($event->job instanceof JobInterface)) { throw new InvalidArgumentException('Job must be instance of JobInterface.'); } if (!is_numeric($event->ttr)) { throw new InvalidArgumentException('Job TTR must be integer.'); } $event->ttr = (int) $event->ttr; if ($event->ttr <= 0) { throw new InvalidArgumentException('Job TTR must be greater that zero.'); } if (!is_numeric($event->delay)) { throw new InvalidArgumentException('Job delay must be integer.'); } $event->delay = (int) $event->delay; if ($event->delay < 0) { throw new InvalidArgumentException('Job delay must be positive.'); } $message = $this->serializer->serialize($event->job); $event->id = $this->pushMessage($message, $event->ttr, $event->delay, $event->priority); $this->trigger(self::EVENT_AFTER_PUSH, $event); return $event->id; } /** * @param string $message * @param int $ttr time to reserve in seconds * @param int $delay * @param mixed $priority * @return string id of a job message */ abstract protected function pushMessage($message, $ttr, $delay, $priority); /** * Uses for CLI drivers and gets process ID of a worker. * * @since 2.0.2 */ public function getWorkerPid() { return null; } /** * @param string $id of a job message * @param string $message * @param int $ttr time to reserve * @param int $attempt number * @return bool */ protected function handleMessage($id, $message, $ttr, $attempt) { list($job, $error) = $this->unserializeMessage($message); $event = new ExecEvent([ 'id' => $id, 'job' => $job, 'ttr' => $ttr, 'attempt' => $attempt, 'error' => $error, ]); $this->trigger(self::EVENT_BEFORE_EXEC, $event); if ($event->handled) { return true; } if ($event->error) { return $this->handleError($event); } try { $event->result = $event->job->execute($this); } catch (\Exception $error) { $event->error = $error; return $this->handleError($event); } catch (\Throwable $error) { $event->error = $error; return $this->handleError($event); } $this->trigger(self::EVENT_AFTER_EXEC, $event); return true; } /** * Unserializes. * * @param string $id of the job * @param string $serialized message * @return array pair of a job and error that */ public function unserializeMessage($serialized) { try { $job = $this->serializer->unserialize($serialized); } catch (\Exception $e) { return [null, new InvalidJobException($serialized, $e->getMessage(), 0, $e)]; } if ($job instanceof JobInterface) { return [$job, null]; } return [null, new InvalidJobException($serialized, sprintf( 'Job must be a JobInterface instance instead of %s.', VarDumper::dumpAsString($job) ))]; } /** * @param ExecEvent $event * @return bool * @internal */ public function handleError(ExecEvent $event) { $event->retry = $event->attempt < $this->attempts; if ($event->error instanceof InvalidJobException) { $event->retry = false; } elseif ($event->job instanceof RetryableJobInterface) { $event->retry = $event->job->canRetry($event->attempt, $event->error); } $this->trigger(self::EVENT_AFTER_ERROR, $event); return !$event->retry; } /** * @param string $id of a job message * @return bool */ public function isWaiting($id) { return $this->status($id) === self::STATUS_WAITING; } /** * @param string $id of a job message * @return bool */ public function isReserved($id) { return $this->status($id) === self::STATUS_RESERVED; } /** * @param string $id of a job message * @return bool */ public function isDone($id) { return $this->status($id) === self::STATUS_DONE; } /** * @param string $id of a job message * @return int status code */ abstract public function status($id); }