diff --git a/psalm.xml b/psalm.xml
index c9de05bc3..d92109732 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -1,6 +1,6 @@
-
-
+
+
+
@@ -24,4 +25,7 @@
+
+
+
diff --git a/src/JobEvent.php b/src/JobEvent.php
index e994161ef..fab622150 100644
--- a/src/JobEvent.php
+++ b/src/JobEvent.php
@@ -25,9 +25,9 @@ abstract class JobEvent extends Event
*/
public $name = '';
/**
- * @var Queue|null|object
+ * @var Queue
* @inheritdoc
- * @psalm-suppress PropertyNotSetInConstructor
+ * @psalm-suppress PropertyNotSetInConstructor, NonInvariantDocblockPropertyType
*/
public $sender;
/**
diff --git a/src/LogBehavior.php b/src/LogBehavior.php
index 5f44acf4a..08df14df8 100644
--- a/src/LogBehavior.php
+++ b/src/LogBehavior.php
@@ -97,9 +97,14 @@ public function afterError(ExecEvent $event): void
*/
public function workerStart(cli\WorkerEvent $event): void
{
- $title = 'Worker ' . $event->sender->getWorkerPid();
+ $workerPid = $event->sender->getWorkerPid();
+ if (null === $workerPid) {
+ $workerPid = '{PID not found}';
+ }
+ $title = 'Worker ' . $workerPid;
Yii::info("$title is started.", Queue::class);
Yii::beginProfile($title, Queue::class);
+
if ($this->autoFlush) {
Yii::getLogger()->flush(true);
}
@@ -111,9 +116,14 @@ public function workerStart(cli\WorkerEvent $event): void
*/
public function workerStop(cli\WorkerEvent $event): void
{
- $title = 'Worker ' . $event->sender->getWorkerPid();
+ $workerPid = $event->sender->getWorkerPid();
+ if (null === $workerPid) {
+ $workerPid = '{PID not found}';
+ }
+ $title = 'Worker ' . $workerPid;
Yii::endProfile($title, Queue::class);
Yii::info("$title is stopped.", Queue::class);
+
if ($this->autoFlush) {
Yii::getLogger()->flush(true);
}
@@ -139,7 +149,9 @@ protected function getExecTitle(ExecEvent $event): string
{
$title = $this->getJobTitle($event);
$extra = "attempt: $event->attempt";
- if ($pid = $event->sender?->getWorkerPid()) {
+
+ $pid = $event->sender->getWorkerPid();
+ if (null !== $pid) {
$extra .= ", PID: $pid";
}
return "$title ($extra)";
diff --git a/src/Queue.php b/src/Queue.php
index 93c01f744..212886fa9 100644
--- a/src/Queue.php
+++ b/src/Queue.php
@@ -224,7 +224,7 @@ protected function handleMessage(int|string $id, string $message, int $ttr, int
return $this->handleError($event);
}
try {
- /** @psalm-suppress PossiblyUndefinedMethod */
+ /** @psalm-suppress PossiblyUndefinedMethod, MixedMethodCall */
$event->result = $event->job?->execute($this);
} catch (Throwable $error) {
$event->error = $error;
diff --git a/src/cli/Action.php b/src/cli/Action.php
index 5e90ac7b8..081a6a159 100644
--- a/src/cli/Action.php
+++ b/src/cli/Action.php
@@ -51,6 +51,7 @@ public function init(): void
/**
* @param string $string
* @return string
+ * @psalm-suppress MixedInferredReturnType, MixedReturnStatement
*/
protected function format(string $string): string
{
diff --git a/src/cli/Command.php b/src/cli/Command.php
index f5fd0e9da..af7cd5e75 100644
--- a/src/cli/Command.php
+++ b/src/cli/Command.php
@@ -124,8 +124,12 @@ public function beforeAction($action): bool
if ($this->phpBinary === null) {
$this->phpBinary = PHP_BINARY;
}
- /** @psalm-suppress MissingClosureReturnType */
- $this->queue->messageHandler = function (int|string|null $id, string $message, int $ttr, int $attempt) {
+ $this->queue->messageHandler = function (
+ int|string|null $id,
+ string $message,
+ int $ttr,
+ int $attempt
+ ): bool {
return $this->handleMessage($id, $message, $ttr, $attempt);
};
}
@@ -178,6 +182,7 @@ protected function handleMessage(int|string|null $id, string $message, ?int $ttr
foreach ($this->getPassedOptions() as $name) {
if (in_array($name, $this->options('exec'), true)) {
+ /** @psalm-suppress MixedOperand */
$cmd[] = '--' . $name . '=' . $this->$name;
}
}
diff --git a/src/cli/Queue.php b/src/cli/Queue.php
index 9dac8a5bd..c041dfff1 100644
--- a/src/cli/Queue.php
+++ b/src/cli/Queue.php
@@ -63,7 +63,7 @@ abstract class Queue extends BaseQueue implements BootstrapInterface
* @var int|null current process ID of a worker.
* @since 2.0.2
*/
- private ?int $_workerPid = null;
+ private ?int $workerPid = null;
/**
* @return string command id
@@ -72,7 +72,7 @@ protected function getCommandId(): string
{
foreach (Yii::$app->getComponents(false) as $id => $component) {
if ($component === $this) {
- return Inflector::camel2id($id);
+ return Inflector::camel2id((string)$id);
}
}
throw new InvalidConfigException('Queue must be an application component.');
@@ -100,7 +100,7 @@ public function bootstrap($app): void
*/
protected function runWorker(callable $handler): ?int
{
- $this->_workerPid = getmypid();
+ $this->workerPid = getmypid();
/** @var LoopInterface $loop */
$loop = Yii::createObject($this->loopConfig, [$this]);
@@ -117,7 +117,7 @@ protected function runWorker(callable $handler): ?int
});
} finally {
$this->trigger(self::EVENT_WORKER_STOP, $event);
- $this->_workerPid = null;
+ $this->workerPid = null;
}
return $event->exitCode;
@@ -132,11 +132,12 @@ protected function runWorker(callable $handler): ?int
*/
public function getWorkerPid(): ?int
{
- return $this->_workerPid;
+ return $this->workerPid;
}
/**
* @inheritdoc
+ * @psalm-suppress MixedReturnStatement, MixedInferredReturnType
*/
protected function handleMessage(int|string $id, string $message, int $ttr, int $attempt): bool
{
@@ -158,7 +159,7 @@ protected function handleMessage(int|string $id, string $message, int $ttr, int
*/
public function execute(string $id, string $message, int $ttr, int $attempt, ?int $workerPid): bool
{
- $this->_workerPid = $workerPid;
+ $this->workerPid = $workerPid;
return parent::handleMessage($id, $message, $ttr, $attempt);
}
}
diff --git a/src/cli/SignalLoop.php b/src/cli/SignalLoop.php
index 46d8897ae..5165117f3 100644
--- a/src/cli/SignalLoop.php
+++ b/src/cli/SignalLoop.php
@@ -21,7 +21,7 @@
class SignalLoop extends BaseObject implements LoopInterface
{
/**
- * @var array of signals to exit from listening of the queue.
+ * @var array of signals to exit from listening of the queue.
*/
public array $exitSignals = [
15, // SIGTERM
@@ -30,12 +30,12 @@ class SignalLoop extends BaseObject implements LoopInterface
1, // SIGHUP
];
/**
- * @var array of signals to suspend listening of the queue.
+ * @var array of signals to suspend listening of the queue.
* For example: SIGTSTP
*/
public array $suspendSignals = [];
/**
- * @var array of signals to resume listening of the queue.
+ * @var array of signals to resume listening of the queue.
* For example: SIGCONT
*/
public array $resumeSignals = [];
diff --git a/src/cli/VerboseBehavior.php b/src/cli/VerboseBehavior.php
index 184930bc7..e4dd27613 100644
--- a/src/cli/VerboseBehavior.php
+++ b/src/cli/VerboseBehavior.php
@@ -36,13 +36,13 @@ class VerboseBehavior extends Behavior
public Controller $command;
/**
- * @var float|null timestamp
+ * @var float timestamp
*/
- private ?float $jobStartedAt = null;
+ private float $jobStartedAt = 0;
/**
- * @var int|null timestamp
+ * @var int timestamp
*/
- private ?int $workerStartedAt = null;
+ private int $workerStartedAt = 0;
/**
* @inheritdoc
@@ -121,7 +121,8 @@ protected function jobTitle(ExecEvent $event): string
{
$name = $event->job instanceof JobInterface ? get_class($event->job) : 'unknown job';
$extra = "attempt: $event->attempt";
- if ($pid = $event->sender?->getWorkerPid()) {
+ $pid = $event->sender->getWorkerPid();
+ if (null !== $pid) {
$extra .= ", pid: $pid";
}
return " [$event->id] $name ($extra)";
diff --git a/src/closure/Behavior.php b/src/closure/Behavior.php
index dd0fe3183..75b051181 100644
--- a/src/closure/Behavior.php
+++ b/src/closure/Behavior.php
@@ -33,8 +33,7 @@ class Behavior extends \yii\base\Behavior
{
/**
* @var Queue
- * @psalm-suppress NonInvariantDocblockPropertyType
- * @psalm-suppress PropertyNotSetInConstructor
+ * @psalm-suppress PropertyNotSetInConstructor, NonInvariantDocblockPropertyType
*/
public $owner;
diff --git a/src/closure/Job.php b/src/closure/Job.php
index 5bcab6984..eb6897c7d 100644
--- a/src/closure/Job.php
+++ b/src/closure/Job.php
@@ -10,6 +10,7 @@
namespace yii\queue\closure;
+use Laravel\SerializableClosure\SerializableClosure;
use Laravel\SerializableClosure\Serializers\Native;
use yii\queue\JobInterface;
use yii\queue\Queue;
@@ -32,13 +33,16 @@ class Job implements JobInterface
*/
public function execute(Queue $queue)
{
- $closure = unserialize($this->serialized)->getClosure();
+ /** @var SerializableClosure $unserialize */
+ $unserialize = unserialize($this->serialized);
+ $closure = $unserialize->getClosure();
$nativeClosure = $closure();
if ($nativeClosure instanceof Native) {
return $nativeClosure();
}
+ /** @psalm-var JobInterface $nativeClosure */
return $nativeClosure->execute($queue);
}
}
diff --git a/src/debug/Panel.php b/src/debug/Panel.php
index bb35b86d3..2dcabeb8d 100644
--- a/src/debug/Panel.php
+++ b/src/debug/Panel.php
@@ -14,6 +14,7 @@
use Yii;
use yii\base\NotSupportedException;
use yii\base\ViewContextInterface;
+use yii\debug\Panel as BasePanel;
use yii\helpers\VarDumper;
use yii\queue\JobInterface;
use yii\queue\PushEvent;
@@ -23,10 +24,11 @@
* Debug Panel.
*
* @author Roman Zhuravlev
+ * @psalm-suppress PropertyNotSetInConstructor
*/
-class Panel extends \yii\debug\Panel implements ViewContextInterface
+class Panel extends BasePanel implements ViewContextInterface
{
- private array $_jobs = [];
+ private array $jobs = [];
/**
* @inheritdoc
@@ -43,7 +45,7 @@ public function init(): void
{
parent::init();
PushEvent::on(Queue::class, Queue::EVENT_AFTER_PUSH, function (PushEvent $event) {
- $this->_jobs[] = $this->getPushData($event);
+ $this->jobs[] = $this->getPushData($event);
});
}
@@ -82,7 +84,7 @@ protected function getPushData(PushEvent $event): array
*/
public function save()
{
- return ['jobs' => $this->_jobs];
+ return ['jobs' => $this->jobs];
}
/**
@@ -98,6 +100,7 @@ public function getViewPath(): string
*/
public function getSummary(): string
{
+ /** @psalm-var array{jobs: array} $this->data */
return Yii::$app->view->render('summary', [
'url' => $this->getUrl(),
'count' => isset($this->data['jobs']) ? count($this->data['jobs']) : 0,
@@ -109,12 +112,15 @@ public function getSummary(): string
*/
public function getDetail(): string
{
+ /** @psalm-var array{jobs: array} $this->data */
$jobs = $this->data['jobs'] ?? [];
foreach ($jobs as &$job) {
+ /** @psalm-var array{sender: string, id: string|int} $job */
$job['status'] = 'unknown';
/** @var Queue $queue */
if ($queue = Yii::$app->get($job['sender'], false)) {
try {
+ /** @psalm-var Queue $queue */
if ($queue->isWaiting($job['id'])) {
$job['status'] = 'waiting';
} elseif ($queue->isReserved($job['id'])) {
diff --git a/src/debug/views/detail.php b/src/debug/views/detail.php
index 2957a4548..fc3480854 100644
--- a/src/debug/views/detail.php
+++ b/src/debug/views/detail.php
@@ -3,10 +3,12 @@
declare(strict_types=1);
/**
- * @var \yii\web\View $this
+ * @var View $this
* @var array $jobs
*/
+
use yii\helpers\Html;
+use yii\web\View;
$styles = [
'unknown' => 'default',
diff --git a/src/debug/views/summary.php b/src/debug/views/summary.php
index c87f88f44..4c25b7ffb 100644
--- a/src/debug/views/summary.php
+++ b/src/debug/views/summary.php
@@ -3,10 +3,13 @@
declare(strict_types=1);
/**
- * @var \yii\web\View $this
+ * @var View $this
* @var string $url
* @var int $count
*/
+
+use yii\web\View;
+
?>