我在yii2中开发了一个使用yiisoft / yii2-queue扩展的项目。此扩展程序存储订单以导出非常大的CSV。 导出的CSV可以正常工作,但有时会抛出图像异常:https://i.imgur.com/nd4zRrI.png
我认为这可能是因为我使用的postgres版本是:x86_64-pc-linux-gnu上的PostgreSQL 10.4(Debian 10.4-2.pgdg90 +1),由gcc(Debian 6.3.0-18)编译+ deb9u1)6.3.0 20170516,64位
我已经读到它对于9.4版有效。 我拥有的扩展程序的配置如下:
'components' => [
'queue' => [
'class' => \yii\queue\db\Queue::class,
'tableName' => '{{%queue}}', // Table name
'channel' => 'default', // Queue channel key
'db' => require(__DIR__ . '/db.php'),
'mutex' => [
'class' => \yii\mutex\PgsqlMutex::class,
'db' => require(__DIR__ . '/db.php'),
],
'mutexTimeout' => 0,
],
]
有人知道为什么会发生此错误以及如何解决该错误吗?
答案 0 :(得分:0)
'mutexTimeout' => 0,
这可能是原因。这意味着该队列将尝试一次获取互斥体,如果失败(在繁忙队列中很有可能),它将抛出此异常。
I added支持PgsqlMutex
中的超时,但是尚未发布具有此功能的版本。我建议使用master
包的yiisoft/yii2
分支并将mutexTimeout
设置为非零值。
答案 1 :(得分:0)
通过更改 vendor / yiisoft / yii2-queue / src / drivers / db / Queue.php 中的两种方法来解决此问题-https://github.com/yiisoft/yii2-queue/pull/362/files 代码:
/**
* @param array $payload
*/
protected function release($payload)
{
$mutex = $this->mutex->acquire(__CLASS__ . $this->channel, $this->mutexTimeout);
try {
if ($this->deleteReleased) {
$this->db->createCommand()->delete(
$this->tableName,
['id' => $payload['id']]
)->execute();
} else {
$this->db->createCommand()->update(
$this->tableName,
['done_at' => time()],
['id' => $payload['id']]
)->execute();
}
} catch (Exception $e) {
\Yii::error($e->getMessage());
} finally {
if ($mutex) {
$this->mutex->release(__CLASS__ . $this->channel);
} else {
\Yii::warning('Queue->release() Has not waited the lock');
}
}
}
/**
* Moves expired messages into waiting list.
*/
private function moveExpired()
{
if ($this->reserveTime !== time()) {
$this->reserveTime = time();
$this->db->createCommand()->update(
$this->tableName,
['reserved_at' => null],
'[[reserved_at]] < :time - [[ttr]] and [[reserved_at]] is not null and [[done_at]] is null',
[':time' => $this->reserveTime]
)->execute();
}
}