2

I've developed a project in yii2 that uses the yiisoft / yii2-queue extension. This extension stores orders to export very large CSVs. The exported CSVs work correctly but from time to time it throws the exception of the image:https://i.sstatic.net/5Rgms.png

I think it may be because of the postgres version I've working with: PostgreSQL 10.4 (Debian 10.4-2.pgdg90 + 1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18 + deb9u1) 6.3.0 20170516 , 64-bit

I have read that for version 9.4 it works. The configuration of the extension that I have is the following:

'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,
    ],
]

Does anyone know why this error occurs and how to fix it?

2 Answers 2

1
'mutexTimeout' => 0,

This is probably the reason. It means that queue will try acquire mutex once, and if it fails (which may be quite likely on busy queue) it will throw this exception.

I added support for timeout in PgsqlMutex, but there was no release with this feature yet. I suggest to use master branch of yiisoft/yii2 package and set mutexTimeout to non-zero value.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the idea. We have been testing the solution. We have removed the mutexTimeout parameter and we have also set it to 3, but time to time the error occurs in both cases. It seems that the error does not have to do with the export function since the error occurs in a "random" way. We will investigate more to see if we find the solution. Any other idea is welcome. :)
DB queue may be quite slow if you have many queued jobs (at least it was slow on MySQL in my case) - it may result such errors if you have multiple workers on busy queue. Also PgsqlMutex is far from perfect, since it does not really wait for the lock, it just retries multiple times until timeout is reached - if you don't have lucky each try may fail even if there were time frames whether lock could be acquired. You may try MysqlMutex, it should be more reliable in this matter.
0

Fix it by change two methods in vendor/yiisoft/yii2-queue/src/drivers/db/Queue.php - https://github.com/yiisoft/yii2-queue/pull/362/files Code:

/**
 * @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();
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.