Skip to content

fix(database): 完善数据库与 Redis 资源生命周期#709

Open
zhibeigg wants to merge 1 commit into
TabooLib:dev/6.3.0from
zhibeigg:fix/703-database-redis-lifecycle
Open

fix(database): 完善数据库与 Redis 资源生命周期#709
zhibeigg wants to merge 1 commit into
TabooLib:dev/6.3.0from
zhibeigg:fix/703-database-redis-lifecycle

Conversation

@zhibeigg

@zhibeigg zhibeigg commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

原有问题

数据库与 Redis 客户端对“资源由谁创建、由谁关闭”缺少一致约定,异步启动与关闭之间也存在竞态:

  • database-player 无法区分外部传入的数据源和模块内部创建的数据源,可能误关共享数据源,也可能遗漏关闭自建数据源。
  • 玩家 Redis 处理器组合了数据库、连接和订阅资源,但关闭时没有完整释放整组资源。
  • Alkaid Redis 的连接、连接器和订阅重连分散管理,重复关闭、关服期间重连和迟到回调可能互相竞争。
  • Lettuce 单机/集群客户端在异步连接、认证或初始化失败后,稍后才完成的资源可能绕过关闭流程继续存活。

典型触发场景与后果

  • 插件使用其他模块共享的数据源后执行 reload/disable:错误关闭会让其他使用者突然失去连接。
  • 插件自己创建连接池但未显式关闭:热重载后连接池和线程不断累积,最终耗尽数据库连接或阻止 JVM 退出。
  • Redis 正在连接、认证、订阅或重连时插件关闭:可能出现关闭后再次连接、重复订阅、双重释放或 use-after-close。
  • 异步启动失败但连接 Future 随后成功:迟到资源无人持有也无人回收,形成隐蔽泄漏。

本 PR 修改

  • database-player 增加明确的数据源所有权和幂等关闭协议,只关闭模块自身拥有的资源。
  • 让玩家 Redis 处理器按组合关系完整释放数据库与 Redis 资源。
  • 集中登记 Alkaid Redis 连接和连接器,关闭时先阻止新注册/重连,再幂等回收现有资源。
  • 重构 Lettuce 单机与集群客户端的异步启动协调、失败传播和分层关闭;停止后才到达的资源会立即回收。
  • 增加数据源所有权、并发关闭、异步启动失败和迟到完成回归测试。

修改目的

建立可预测的资源所有权和生命周期边界,保证插件启停、重载及连接失败时不会误关共享资源,也不会泄漏连接、线程或订阅任务。

兼容性与行为变化

  • 不引入阻塞等待,数据库与 Redis I/O 仍保持异步。
  • 公开调用方式保持兼容;关闭操作改为可重复调用且结果确定。
  • 插件停止后不再接受迟到连接或继续重连。

验证

  • ./gradlew :module:database:database-player:test :module:database:database-alkaid-redis:test :module:database:database-player-redis:build :module:database:database-lettuce-redis:test --no-daemon --stacktrace
  • git diff --check
  • 最终只读复审未发现高、中严重问题

Refs #703

确保数据源、连接、客户端和线程资源在启动失败、重连及并发关服场景下可靠释放,并补充相关回归测试。
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

Successfully merging this pull request may close these issues.

1 participant