Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

queue jobs interaction with DB connection #12

Closed
ArsSirek opened this issue Feb 27, 2017 · 9 comments
Closed

queue jobs interaction with DB connection #12

ArsSirek opened this issue Feb 27, 2017 · 9 comments

Comments

@ArsSirek
Copy link
Contributor

Hi,
Thanks for the great work, your extension was the most easy to install and use among all I found.

I recently saw errors in my logs saying - "General error: 2006 MySQL server has gone away"
If I am running ./yii queue/listen, and most of the jobs requires to execute a select queries. If i get it right, the connection will be created only once, and jobs that come after hours will not be able to connect to database? (I am connecting remotely to mysql)
It seems to me that extending connection with logic suggested by AnatolyRugalev is one of the best options I can go?

Is this a standard situation to run select queries in queue jobs?
Should we try to write sample db/Connection component and leave a note in docs for those who will want to use db connection in queue jobs?

@ArsSirek
Copy link
Contributor Author

Для подключений к базе комментарий тоже актуален?
т.е., для быстрого переподключения я могу перед исполнением задачи добавить
Yii::$app->set('db', Yii::$app->getComponents()['db']); ?

@ArsSirek
Copy link
Contributor Author

ArsSirek commented Mar 3, 2017

Yii::$app->set('db', Yii::$app->getComponents()['db']); - создаёт новое подключение, но не закрывает предыдущего.

Решение конечно недоработанное, (based on comment ) но для случая, когда запросы только на чтение думаю подойдёт, если вдруг кому-то пригодится, или кто-то может прокомментировать, отпишусь как я в итоге сделал.
` use Yii;
use yii\base\Object;
use yii\db\Exception;
use zhuravljov\yii\queue\Job;
abstract class DBJob extends Object implements Job {

public static $name = "job name";
protected abstract function actualAction();

public function run() {
    echo "executing job " . static::$name . " \n";
    $time = microtime( true );
    try {
        $this->actualAction();
    } catch (Exception $e) {
        $this->reconnect();
        $this->actualAction();
    }
    echo ' > done ' . static::$name . ' (time: ' . sprintf( '%.3f', microtime( true ) - $time ) . "s)\n";
}

protected function reconnect() {
    echo " > > reconnecting to db\n";
    Yii::$app->db->close();
    Yii::$app->db->open();
}

} `
в итоге, Job ы наследующие от DBJob, упираясь в dbEception, будут повторены, после переподключения, и повторная ошибка уже не ловится, т.е. должна будет попасть в лог, как если бы небыло этой обёртки. (не тестировал ещё)

@zhuravljov
Copy link
Member

Я сделал бы через Queue::EVENT_BEFORE_WORK:

class ReconnectBehavior extends Behavior
{
    public function events()
    {
        return [
            Queue::EVENT_BEFORE_WORK => function () {
                try {
                    Yii::$app->db->createCommand('SELECT 1')->execute();
                } catch (\Exception $e) {
                    Yii::$app->db->close();
                    Yii::$app->db->open();
                }
            },
        ];
    }
}

Но это все костыли. Есть мысль запускать задания в отдельных дочерних процессах, чтобы основному процессу воркера оставить только опрос очереди.

@zhuravljov
Copy link
Member

Related #18.

@zhuravljov
Copy link
Member

Сделал так, чтобы задания выполнялись в отдельных дочерних процессах, а воркер только опрашивал очередь. Это должно решить проблемы с отваливающимися сокетами в компонентах db, mailer и прочих, где это актуально. Потестить можно из ветки master.

@metalagman
Copy link

@zhuravljov выполнение заданий в дочерних процессах это тупик, т.к. на каждый таск тебе нужно проинициализировать приложение целиком, это очень сильно гасит производительность

@zhuravljov
Copy link
Member

@russianlagman это опция. Хотите обслуживать сокеты, и следить за утечками памяти самостоятельно - отключайте isolate-режим. И почему тупик? С таким же успехом тупиком ошибочно можно обозначить все, что уровнем выше ассемблера. Требует больше ресурсов и гасит производительность.

@metalagman
Copy link

Надо бы раскрыть этот момент в доке. Много времени потратил на профилирование, почему при переносе кода в джобы производительность упала на порядок.

@YanAlex
Copy link

YanAlex commented Oct 25, 2021

Сталкиваюсь с такой же ошибкой, через N часов простоя CLI просто перестает отвечать, в MYSQL вижу что коннект с пользователем для YII просто оборвался, после нажатия на ENTER и вываливается ошибка "General error: 2006 MySQL server has gone away", все это происходит в isolate=1 режиме. В isolate=0 все работает отлично по несколько дней. Mysq wait_time = 28800, задания приходят раз в день.

Я до конца так и не понял, если коннект инициализируется в воркере и потом просто отдается каждому воркеру, то он будет неизбежно отваливаться каждый раз по окончании тайм-аута.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants