Skip to content

建议:添加 Worker 级别的数据库连接清理机制 #24

Description

@21307369

问题背景

在 webman + Swoole 环境下,当 Worker 进程退出时,ThinkPHP ORM 的 PDOConnection::__destruct() 会触发 Swoole 协程错误(详见 top-think/think-orm#853)。

虽然这是上游 think-orm 的 bug,但 webman 的 think-orm 插件可以在 DbManager 层面提供防御性清理机制。

当前行为

DbManager 使用 Context::onDestroy() 在请求结束时将连接返回连接池:

// vendor/webman/think-orm/src/DbManager.php:76-82
Context::onDestroy(function () use ($connection, $name) {
    try {
        $connection && static::$pools[$name]->put($connection);
    } catch (Throwable) {
        // ignore
    }
});

但这只处理请求级清理,不处理 Worker 级退出。

建议方案

DbManager 中添加静态方法,用于在 Worker 停止前清理所有连接:

/**
 * 关闭所有连接池(Worker 停止时调用)
 */
public static function closeAllPools(): void
{
    foreach (static::$pools as $name => $pool) {
        // 关闭 Context 中持有的连接
        $key = "think-orm.connections.$name";
        $connection = \Webman\Context::get($key);
        if ($connection) {
            try {
                $connection->close();
            } catch (\Throwable $e) {
                // ignore
            }
            \Webman\Context::set($key, null);
        }

        // 关闭池中的空闲连接
        try {
            $pool->closeConnections();
        } catch (\Throwable $e) {
            // ignore
        }
    }
}

然后在 ThinkOrm bootstrap 类中注册 onWorkerStop 回调:

// vendor/webman/think-orm/src/ThinkOrm.php
public static function start($worker): void
{
    // ... 现有初始化代码 ...

    if ($worker) {
        $worker->onWorkerStop = function () {
            DbManager::closeAllPools();
        };
    }
}

优势

  1. 集中管理:连接清理逻辑在插件内部,用户无需手动处理
  2. 防御性编程:即使上游 think-orm 未修复,也能避免错误
  3. 向后兼容:不影响现有功能,只是增加了 Worker 退出时的清理

环境信息

  • PHP: 8.4.22
  • Swoole: 6.2.1
  • webman: 2.2.1
  • webman/think-orm: 2.1.x
  • topthink/think-orm: 4.0.51

相关 Issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions