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

Swoole 4.2.3 Task中使用协程MySQL报错 #2041

Closed
hhxsv5 opened this issue Oct 16, 2018 · 20 comments
Closed

Swoole 4.2.3 Task中使用协程MySQL报错 #2041

hhxsv5 opened this issue Oct 16, 2018 · 20 comments
Labels

Comments

@hhxsv5
Copy link

hhxsv5 commented Oct 16, 2018

Please answer these questions before submitting your issue. Thanks!

  1. What did you do? If possible, provide a simple script for reproducing the error.
    Swoole 4.2.3 Task中使用协程MySQL报错
$swoole_mysql = new \Swoole\Coroutine\MySQL();
$swoole_mysql->connect([
    'host'     => 'mysql',
    'port'     => 3306,
    'user'     => 'root',
    'password' => 'abc123',
    'database' => 'test',
]);
$res = $swoole_mysql->query('select sleep(1)');
var_dump($res);
  1. What did you expect to see?
    正常执行协程MySQL

  2. What did you see instead?

[2018-10-16 18:48:24 ^369.1]	ERROR	zm_deactivate_swoole (ERROR 503): Fatal error: App\Tasks\TestTask::handle(): must be called in the coroutine. in /docker/www/laravel-s-test/app/Tasks/TestTask.php on line 29.
[2018-10-16 18:48:24 $367.0]	WARNING	swManager_check_exit_status: worker#1 abnormal exit, status=255, signal=0
  1. What version of Swoole are you using (show your php --ri swoole)?
    4.2.3

  2. What is your machine environment used (including version of kernel & php & gcc) ?
    Debian GNU/Linux 8 \n \l
    PHP 7.1.21 (cli) (built: Sep 7 2018 22:17:18) ( NTS )
    gcc version 4.9.2 (Debian 4.9.2-10+deb8u1)

@twose
Copy link
Member

twose commented Oct 16, 2018

用go方法创建协程再使用,允许使用但不是自动创建协程。

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 16, 2018

谢谢,明白了。

另外Task中支持协程Runtime吗?

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 16, 2018

尝试在Task中开启Runtime,但报错了。

//Task中
\Swoole\Runtime::enableCoroutine();
$pdo = new \PDO('mysql:dbname=test;host=mysql', 'root', 'abc123');
$sql = sprintf('insert into test(name,created_at,updated_at) values("%s","%s","%s")', uniqid(), date('Y-m-d H:i:s'), date('Y-m-d H:i:s'));
$ret = $pdo->exec($sql);
var_dump($ret);
[2018-10-16 19:26:13 ^828.1]	WARNING	yield: Socket::yield() must be called in the coroutine.
[2018-10-16 19:26:13 $826.0]	WARNING	swManager_check_exit_status: worker#1 abnormal exit, status=0, signal=11
A bug occurred in Swoole-v4.2.3, please report it.
The Swoole developers probably don't know about it,
and unless you report it, chances are it won't be fixed.
You can read How to report a bug doc before submitting any bug reports:
>> https://github.com/swoole/swoole-src/issues/2000
Please do not send bug reports in the mailing list or personal letters.
The issue page is also suitable to submit feature requests.

@twose
Copy link
Member

twose commented Oct 16, 2018

@hhxsv5
涉及协程的都需要在go中, 除非是支持自动化协程的回调.
可以通过 co::getuid 是否为 大于0 的数字 来判断是否在协程中
这里底层缺少了检测, 所以出错了

@twose twose added the question label Oct 16, 2018
@xiangjihan
Copy link

现在搞不清楚,哪些地方是自动创建协程的,哪些需要手动创建。

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 17, 2018

@xiangjihan 根据文档,swoole_server和swoole_http_server将为每一个请求创建对应的协程,可以在onRequet、onReceive、onConnect中使用,其他地方都需手动创建协程, @twose 我的理解是否正确?

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 17, 2018

测试了下,在Task中使用启用协程Runtime,第一次执行成功,第二次开始报错。

go(function () {
    \Swoole\Runtime::enableCoroutine(); #注释掉这行就正常
    $pdo = new \PDO('mysql:dbname=test;host=mysql', 'root', 'abc123');
    $sql = sprintf('insert into test(name,created_at,updated_at) values("%s","%s","%s")', uniqid(), date('Y-m-d H:i:s'), date('Y-m-d H:i:s'));
    $ret = $pdo->exec($sql);
    var_dump($ret);
});
  [Symfony\Component\Debug\Exception\FatalErrorException]
  Uncaught ErrorException: PDO::exec(): MySQL server has gone away in /docker/www/laravel-s-test/app/Tasks/TestTask.php:47
  Stack trace:
  #0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'PDO::exec(): My...', '/docker/www/lar...', 47, Array)
  #1 /docker/www/laravel-s-test/app/Tasks/TestTask.php(47): PDO->exec('insert into tes...')
  #2 {main}
    thrown

@twose
Copy link
Member

twose commented Oct 18, 2018

@hhxsv5 理解正确, 稍后我添加一个相关单元测试
关于自动创建协程的范围: https://wiki.swoole.com/wiki/page/949.html

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 18, 2018

@twose 上面那个报错是怎么回事啊

@twose
Copy link
Member

twose commented Oct 18, 2018

@hhxsv5 断线了需要重新创建连接

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 19, 2018

我是worker和task worker数都置为1,投递了三次任务,任务中go开协程连接数据库执行sql,第二次任务开始就报MySQL server has gone away
这不科学,每次任务都是新协程、新数据库连接。 @twose

@twose
Copy link
Member

twose commented Oct 20, 2018

@hhxsv5
可以贴一下简单的代码复现这个问题吗, 我这边尝试复现一下.

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 22, 2018

😢github 出bug了,贴了N次,贴不上。

@tracy-ling
Copy link

@twose

<?php
$http = new swoole_http_server('127.0.0.1', 5200);
$http->set([
    'daemonize'       => false,
    'worker_num'      => 1,
    'task_worker_num' => 1,
]);
$http->on('Request', function (swoole_http_request $request, swoole_http_response $response) use ($http) {
    $taskId = $http->task('run');
    $response->end('Hello LaravelS #' . $taskId);
});
$http->on('Task', function (swoole_http_server $server, $taskId, $srcWorkerId, $data) {
    go(function () {
        \Swoole\Runtime::enableCoroutine(); #注释掉这行就正常
        $pdo = new PDO('mysql:dbname=test;host=127.0.0.1', 'root', 'xy123456');
        $sql = sprintf('insert into test(name,created_at,updated_at) values("%s","%s","%s")', uniqid(),
            date('Y-m-d H:i:s'), date('Y-m-d H:i:s'));
        $pdo->exec($sql);
        var_dump($pdo->lastInsertId());
    });
});
$http->on('Finish', function (swoole_http_server $server, $taskId, $data) {

});
$http->start();
→ php task.php
PHP Warning:  Unknown: onTask handler error. in Unknown on line 0

Warning: Unknown: onTask handler error. in Unknown on line 0
PHP Fatal error:  Uncaught PDOException: PDO::__construct(): MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}

Next PDOException: SQLSTATE[HY000] [2006] MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}
  thrown in /Users/dave/Documents/docker/www/laravel-s-test/task.php on line 15

Fatal error: Uncaught PDOException: PDO::__construct(): MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}

Next PDOException: SQLSTATE[HY000] [2006] MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}
  thrown in /Users/dave/Documents/docker/www/laravel-s-test/task.php on line 15
[2018-10-22 11:33:55 ^42927.1]  ERROR   zm_deactivate_swoole (ERROR 503): Fatal error: Uncaught PDOException: PDO::__construct(): MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}

Next PDOException: SQLSTATE[HY000] [2006] MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/la
[2018-10-22 11:33:55 $42926.0]  WARNING swManager_check_exit_status: worker#1 abnormal exit, status=255, signal=0

1 similar comment
@hhxsv5
Copy link
Author

hhxsv5 commented Oct 22, 2018

@twose

<?php
$http = new swoole_http_server('127.0.0.1', 5200);
$http->set([
    'daemonize'       => false,
    'worker_num'      => 1,
    'task_worker_num' => 1,
]);
$http->on('Request', function (swoole_http_request $request, swoole_http_response $response) use ($http) {
    $taskId = $http->task('run');
    $response->end('Hello LaravelS #' . $taskId);
});
$http->on('Task', function (swoole_http_server $server, $taskId, $srcWorkerId, $data) {
    go(function () {
        \Swoole\Runtime::enableCoroutine(); #注释掉这行就正常
        $pdo = new PDO('mysql:dbname=test;host=127.0.0.1', 'root', 'xy123456');
        $sql = sprintf('insert into test(name,created_at,updated_at) values("%s","%s","%s")', uniqid(),
            date('Y-m-d H:i:s'), date('Y-m-d H:i:s'));
        $pdo->exec($sql);
        var_dump($pdo->lastInsertId());
    });
});
$http->on('Finish', function (swoole_http_server $server, $taskId, $data) {

});
$http->start();
→ php task.php
PHP Warning:  Unknown: onTask handler error. in Unknown on line 0

Warning: Unknown: onTask handler error. in Unknown on line 0
PHP Fatal error:  Uncaught PDOException: PDO::__construct(): MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}

Next PDOException: SQLSTATE[HY000] [2006] MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}
  thrown in /Users/dave/Documents/docker/www/laravel-s-test/task.php on line 15

Fatal error: Uncaught PDOException: PDO::__construct(): MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}

Next PDOException: SQLSTATE[HY000] [2006] MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}
  thrown in /Users/dave/Documents/docker/www/laravel-s-test/task.php on line 15
[2018-10-22 11:33:55 ^42927.1]  ERROR   zm_deactivate_swoole (ERROR 503): Fatal error: Uncaught PDOException: PDO::__construct(): MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/laravel-s-test/task.php(15): PDO->__construct('mysql:dbname=te...', 'root', 'xy123456')
#1 {main}

Next PDOException: SQLSTATE[HY000] [2006] MySQL server has gone away in /Users/dave/Documents/docker/www/laravel-s-test/task.php:15
Stack trace:
#0 /Users/dave/Documents/docker/www/la
[2018-10-22 11:33:55 $42926.0]  WARNING swManager_check_exit_status: worker#1 abnormal exit, status=255, signal=0

@twose
Copy link
Member

twose commented Oct 22, 2018

确认是PHP71的PDO的问题, PHP72无此问题, 待追踪

@twose
Copy link
Member

twose commented Oct 22, 2018

你的MySQL版本是?

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 22, 2018

github还没恢复...

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 22, 2018

@twose 5.7.23 5.7.21 两个版本都试过。

@hhxsv5
Copy link
Author

hhxsv5 commented Oct 23, 2018

@twose 好的,需要新开个issue吗?

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

No branches or pull requests

4 participants