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

Feature perfect swoole extension config #297

Merged
merged 99 commits into from
Jan 3, 2024

Conversation

jingjingxyk
Copy link
Contributor

@jingjingxyk jingjingxyk commented Dec 24, 2023

完善 swoole 扩展静态编译

@crazywhalecc crazywhalecc added wip Work In Process kind/extension Issues related to extensions labels Dec 24, 2023
@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 27, 2023

@jingjingxyk jingjingxyk reopened this Dec 27, 2023
@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 27, 2023

目前我的决策还是不把 swoole 当作一个框架,继续作为扩展,因为 static-php-cli 是用于编译 PHP 的,而不是构建框架的。如果要实现框架一样的比较高耦合的项目的话,我更建议将 static-php-cli 作为依赖,然后将所需要的所有东西编译进去,就像 FrankenPHP 和 Laravel Herd。

另外有关协程的问题,我了解过但不参与讨论。我也写过框架,最后发现一切还是要大道至简。

@jingjingxyk
Copy link
Contributor Author

目前我的决策还是不把 swoole 当作一个框架,继续作为扩展,因为 static-php-cli 是用于编译 PHP 的,而不是构建框架的。如果要实现框架一样的比较高耦合的项目的话,我更建议将 static-php-cli 作为依赖,然后将所需要的所有东西编译进去,就像 FrankenPHP 和 Laravel Herd。

另外有关协程的问题,我了解过但不参与讨论。我也写过框架,最后发现一切还是要大道至简。

按你说的办

@crazywhalecc
Copy link
Owner

我搞清楚了,上面的 pdo 是因为你在测试过程中发现缺少头文件导致的,因为必须启用 pdo 扩展才能包含 pdo/pdo.h,才能 Hook pdo_。然后不能启用 pdo_ 的原因是 swoole 的 pdo_driver 和原有的 pdo_driver 不能链接到一起。所以应该是一个依赖 provide 的关系,Swoole 提供了 pdo_* 的扩展内容,启用这些特性时不能启用原来的 pdo_*。

@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 27, 2023

目前测试了下,如果使用不启用 pdo_pgsql 扩展、启用 Swoole 的 pgsql hook,是没办法正常使用 new PDO('pgsql:host=127.0.0.1;port=5432;dbname=postgres'),执行到这句代码会卡住,而使用 pdo_pgsql 扩展才是正常的(在 macOS 下)。Linux 下是正常的,不知道是哪里出了问题。

  • 使用 Swoole 的 pgsql 支持时,编译的扩展有:zlib, openssl, curl, pgsql, pdo, swoole
  • 使用 pdo_pgsql 时,编译的扩展有:pdo, pgsql, pdo_pgsql

感觉可能是 Swoole 自身或者 postgresql 的老问题,因为我在 macOS 连接的 postgres 数据库是 14,Linux 上是 15,Swoole 都使用的稳定版(5.1.1)。

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

似乎主要是 DSN 的写法不同

协程的写法,应该运行在协程运行时中。

启动 pgsql 数据库例子:

version: "3"
services:
    postgresql-server:
        image: postgres:15-alpine
        hostname: "postgresql"
        ports:
            - "5432:5432"
        environment:
            - "POSTGRES_PASSWORD=example"
        
        # 容器内数据目录 /var/lib/postgresql/data
        # auth_user: postgres
        # auth_password: example

swoole 以协程的方式连接 PGSQL 例子

文档: https://wiki.swoole.com/#/coroutine_client/postgresql

<?php

declare(strict_types=1);

use Swoole\Coroutine\PostgreSQL;

use function Swoole\Coroutine\run;

run(function () {
    $pg = new PostgreSQL();
    //pdo_pgsql DSN 写法:  'pgsql:host=127.0.0.1;port=5432;dbname=postgres'
    $conn = $pg->connect('host=127.0.0.1 port=5432 dbname=postgres user=postgres password=example');
    if (!$conn) {
        var_dump($pg->error);
        return;
    }
    // $stmt = $pg->query('select * from pg_tables;');
    $stmt = $pg->query('SELECT version();');
    $stmt = $pg->query('SHOW search_path;');
    $stmt = $pg->query('select now();');
    $stmt = $pg->query('select * from information_schema.columns ');
    $stmt = $pg->query('SELECT * from  pg_stat_activity;');
    // $stmt = $pg->query('SELECT * FROM test;');
    $arr = $stmt->fetchAll();
    var_dump($arr);
});

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

对于macos 下载构建好的包,这里下载的构建软件包 https://github.com/jingjingxyk/static-php-cli/actions/runs/7344504695

# Mac安装应用“提示文件已损坏”或“来自身份不明开发者”解决方法
sudo xattr -d com.apple.quarantine ./php

# 查看链接的系统库信息
otool -L ./php

image
image

用构建好的包测试了一遍,没有你说的这个问题哈。

最大的区别就是构建参数不太一样。
构建配置:(分支feature-swoole-my) https://raw.githubusercontent.com/jingjingxyk/static-php-cli/feature-swoole-my/src/globals/test-extensions.php

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

目前测试了下,如果使用不启用 pdo_pgsql 扩展、启用 Swoole 的 pgsql hook,是没办法正常使用 new PDO('pgsql:host=127.0.0.1;port=5432;dbname=postgres'),执行到这句代码会卡住,而使用 pdo_pgsql 扩展才是正常的(在 macOS 下)。Linux 下是正常的,不知道是哪里出了问题。

* 使用 Swoole 的 pgsql 支持时,编译的扩展有:`zlib, openssl, curl, pgsql, pdo, swoole`。

* 使用 pdo_pgsql 时,编译的扩展有:`pdo, pgsql, pdo_pgsql`。

感觉可能是 Swoole 自身或者 postgresql 的老问题,因为我在 macOS 连接的 postgres 数据库是 14,Linux 上是 15,Swoole 都使用的稳定版(5.1.1)。

需要检查编译链接时,是否链接到了系统提供的 libpq 库 ,你再用上面的例子试一试

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

我搞清楚了,上面的 pdo 是因为你在测试过程中发现缺少头文件导致的,因为必须启用 pdo 扩展才能包含 pdo/pdo.h,才能 Hook pdo__。然后不能启用 pdo__ 的原因是 swoole 的 pdo_driver 和原有的 pdo_driver 不能链接到一起。所以应该是一个依赖 provide 的关系,Swoole 提供了 pdo_* 的扩展内容,启用这些特性时不能启用原来的 pdo_*。

对,是这么回事。

swoole 提供数据库协程实现原理: 是在 pdo_* 基础上,添加了协程调度。 详情见这里: https://github.com/swoole/swoole-src/tree/master/thirdparty/php81

出现扩展互斥这个问题,其实是因为原生就没有提供协程调度、事件循环、协程调度 等功能,目前也没有统一的标准。
也就是这个讨论很激烈的问题: https://zhuanlan.zhihu.com/p/356942841

@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 28, 2023

需要检查编译链接时,是否链接到了系统提供的 libpq 库 ,你再用上面的例子试一试

这些我肯定会确认好的,否则不会轻易得出无法连接的结论。另外,macOS 平台我也只尝试了 arm64 架构,x86_64 架构不排除会有不一样的结论。

更新:x86_64 也确定会卡住。

启动 pgsql 数据库例子:

我主要是测试 pdo_pgsql 能否正常使用,与 Swoole 自身的客户端和 pgsql 扩展无关,这两个可以正常使用。

@crazywhalecc
Copy link
Owner

应该就是静态 php 和 swoole 的 hook 导致的问题,我刚才也尝试了 macOS 的 swoole-cli 也是存在这个问题的。

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

应该就是静态 php 和 swoole 的 hook 导致的问题,我刚才也尝试了 macOS 的 swoole-cli 也是存在这个问题的。

<?php

declare(strict_types=1);

try {
    $dbh = new PDO('pgsql:dbname=postgres host=127.0.0.1 port=5432 ', 'postgres', 'example');

    $stmt = $dbh->prepare('SELECT version()');
    $stmt->execute();
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    var_dump($result);

    $stmt = $dbh->prepare('SELECT * from  pg_stat_activity');
    $stmt->execute();
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    var_dump($result);
    $dbh = null;
} catch (PDOException $e) {
    exit('Database connection failed: ' . $e->getMessage());
}

上面是测试脚本

你的编译配置是啥?

1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性
2、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展, 不启用 swoole扩展的coroutine_pgsql 特性
3、 编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展, 不启用swoole扩展的coroutine_pgsql 特性
4、 编译时 不启用 swoole 扩展 ,启用 pdo_pgsql 扩展
5、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性。这个是无法编译通过的 (详情: https://github.com/jingjingxyk/static-php-cli/actions/runs/7346590267)

swoole-cli 默认并不包括 pdo_pgsql 这个扩展,使用上述代码测试(new PDO('pgsql:dbname=postgres host=127.0.0.1 port=5432 ', 'postgres', 'example');),应该出现报错, 而不是卡住 。报错信息 (Database connection failed: could not find driver)

image

@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 28, 2023

就是卡住了,执行到 new PDO 这句,就不动了。

image

而 pecl install swoole 安装的没有问题。

image

编译配置使用的是 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性

使用编译配置 2、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展, 不启用 swoole扩展的coroutine_pgsql 特性 时,也可以正常执行。

我先本地 lldb 调试一下,看看能不能找到卡住的位置。

@jingjingxyk
Copy link
Contributor Author

就是卡住了,执行到 new PDO 这句,就不动了。
image

而 pecl install swoole 安装的没有问题。
image

编译配置使用的是 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性

使用编译配置 2、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展, 不启用 swoole扩展的coroutine_pgsql 特性 时,也可以正常执行。

就是卡住了,执行到 new PDO 这句,就不动了。
image

而 pecl install swoole 安装的没有问题。
image

编译配置使用的是 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性

使用编译配置 2、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展, 不启用 swoole扩展的coroutine_pgsql 特性 时,也可以正常执行。

我先本地 lldb 调试一下,看看能不能找到卡住的位置。

使用 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性。 连接的时候,应该是报错,报错信息提示应该是是 could not find driver ,出现卡着,很奇怪呀。 调试工具 https://wiki.swoole.com/#/other/tools?id=gdb

@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 28, 2023

使用 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性。 连接的时候,应该是报错,报错信息提示应该是是 could not find driver

不,在 Linux 下是正常的。macOS 下使用 brew install php 和 pecl install swoole 安装后也是正常的。

出现卡着,很奇怪呀。

确实奇怪。我刚才调试了发现它卡到 libpq 中了,栈里也调用到 swoole 了,但还是不知道为什么卡住。

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

使用 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性。 连接的时候,应该是报错,报错信息提示应该是是 could not find driver

不,在 Linux 下是正常的。macOS 下使用 brew install php 和 pecl install swoole 安装后也是正常的。

出现卡着,很奇怪呀。

确实奇怪。我刚才调试了发现它卡到 libpq 中了,栈里也调用到 swoole 了,但还是不知道为什么卡住。

我又看了看文档,看到了这个: Swoole5.0 之前是使用协程客户端进行对 PostgreSQL 进行协程化,Swoole5.1 之后,除了使用协程客户端进行协程化,也能够使用原生的 pdo_pgsql 协程化 PostgreSQL 了

https://wiki.swoole.com/#/environment?id=-enable-swoole-pgsql

@crazywhalecc crazywhalecc merged commit 31c71f1 into crazywhalecc:main Jan 3, 2024
13 checks passed
@jingjingxyk jingjingxyk deleted the feature-swoole branch October 9, 2024 02:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/extension Issues related to extensions need test This PR has not been tested yet, cannot merge now
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants