Skip to content

【企业微信】重构会话存档SDK生命周期为ThreadLocal模式#3935

Merged
binarywang merged 11 commits intobinarywang:developfrom
OldQi:develop
Mar 22, 2026
Merged

【企业微信】重构会话存档SDK生命周期为ThreadLocal模式#3935
binarywang merged 11 commits intobinarywang:developfrom
OldQi:develop

Conversation

@OldQi
Copy link
Contributor

@OldQi OldQi commented Mar 18, 2026

  • 移除7200秒过期和引用计数机制,解决频繁初始化及线程安全问题
  • 每线程持有独立SDK实例,实现懒初始化和线程内复用
  • 新增closeThreadLocalSdk()和closeAllSdks()接口,用于显式释放资源
  • 废弃WxCpConfigStorage中旧的SDK管理方法及相关字段,保留兼容实现
  • 更新WxCpMsgAuditServiceImpl,实现ThreadLocal管理SDK实例
  • 修改API调用逻辑,移除获取和释放SDK的旧流程,简化调用流程
  • 补充单元测试覆盖多线程及线程池场景验证安全性
  • 更新相关文档,增加使用示例与注意事项指导正确使用方法

- 移除7200秒过期和引用计数机制,解决频繁初始化及线程安全问题
- 每线程持有独立SDK实例,实现懒初始化和线程内复用
- 新增closeThreadLocalSdk()和closeAllSdks()接口,用于显式释放资源
- 废弃WxCpConfigStorage中旧的SDK管理方法及相关字段,保留兼容实现
- 更新WxCpMsgAuditServiceImpl,实现ThreadLocal管理SDK实例
- 修改API调用逻辑,移除获取和释放SDK的旧流程,简化调用流程
- 补充单元测试覆盖多线程及线程池场景验证安全性
- 更新相关文档,增加使用示例与注意事项指导正确使用方法
@OldQi OldQi changed the title refactor(msg-audit): 重构会话存档SDK生命周期为ThreadLocal模式 【企业微信】重构会话存档SDK生命周期为ThreadLocal模式 Mar 18, 2026
OldQi added 3 commits March 18, 2026 11:32
- 将获取或初始化SDK的方法替换为直接创建SDK
- 简化了SDK的调用流程
- 提高代码清晰度和维护性
- 移除 managedSdks 集合及相关代码,不再统一追踪所有SDK实例
- 采用ThreadLocal懒初始化,线程内部复用SDK实例
- closeAllSdks() 方法改为调用 closeThreadLocalSdk(),只清理当前线程资源
- 保留旧API方法,内部调用统一替换为 getOrInitThreadLocalSdk()
- 文档更新,明确多线程和多实例场景下的SDK管理及DestroySdk调用规范
- 删除手动调用 Finance.DestroySdk() 的旧测试代码示例,防止误用造成内存泄漏
@binarywang
Copy link
Owner

auggie review

@augmentcode
Copy link

augmentcode bot commented Mar 18, 2026

🤖 Augment PR Summary

Summary: This PR refactors the WeCom (企业微信) message-audit SDK lifecycle from a shared/expiry/ref-count model to a per-thread ThreadLocal model to improve safety and reduce repeated init.

Changes:

  • Introduce per-thread SDK instance management in WxCpMsgAuditServiceImpl with lazy init and thread-local reuse.
  • Remove the 7200s “expires” rule and the reference-count acquire/release flow from the runtime path.
  • Add explicit resource release APIs to WxCpMsgAuditService: closeThreadLocalSdk() and closeAllSdks().
  • Deprecate legacy SDK lifecycle/cache/ref-count methods in WxCpConfigStorage and mark legacy fields/methods as deprecated in WxCpDefaultConfigImpl while keeping compatibility.
  • Simplify safe APIs (getChatRecords/getDecryptChatData/downloadMediaFile) to use thread-local SDK without per-call release.
  • Update unit tests to cover the new safe APIs and demonstrate finally-block cleanup for thread-pool reuse scenarios.
  • Add design documentation describing the ThreadLocal lifecycle approach and recommended usage patterns.

Technical Notes: Uses a concurrent set to track created SDK ids for bulk cleanup; callers in thread pools are expected to call closeThreadLocalSdk() in finally to avoid long-lived native resources.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 4 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

本次 PR 针对企业微信“会话存档”能力重构原生 Finance SDK 的生命周期管理方式,目标是减少频繁初始化/销毁并降低多线程共享句柄带来的线程安全风险,通过 ThreadLocal 让每个线程持有独立 SDK 实例,并提供显式资源释放接口。

Changes:

  • WxCpMsgAuditServiceImpl 中引入 ThreadLocal<Long>managedSdks,新增 closeThreadLocalSdk() / closeAllSdks(),并将推荐 API(不暴露 sdk)切换为线程内复用模式。
  • WxCpConfigStorageWxCpDefaultConfigImpl 中旧的“SDK缓存/过期/引用计数”相关字段与方法标记为 @Deprecated 以保持兼容。
  • 调整测试用例示例,强调线程池场景需在 finally 中调用 closeThreadLocalSdk();新增一份设计说明文档。

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java 用 ThreadLocal 管理会话存档 SDK,新增显式关闭接口并简化推荐 API 调用链
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMsgAuditService.java 对外暴露 closeThreadLocalSdk()/closeAllSdks() 生命周期接口
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java 废弃旧的 SDK 缓存/过期/引用计数 API(保留以兼容)
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java 废弃旧字段与实现方法,继续提供兼容行为
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMsgAuditTest.java 更新示例测试:在 finally 调用 closeThreadLocalSdk()
docs/giggly-pondering-turtle.md 新增 ThreadLocal 生命周期重构方案说明文档

@binarywang
Copy link
Owner

@OldQi 麻烦处理下上面的review建议,如果无需修改,备注后resolve conversation即可

OldQi added 7 commits March 22, 2026 01:12
- 移除7200秒过期机制和引用计数,采用ThreadLocal为每个线程持有独立SDK实例
- 新增getOrInitThreadLocalSdk()方法实现线程内SDK复用,避免频繁初始化/销毁
- 添加closeThreadLocalSdk()和closeAllSdks()方法用于显式清理SDK资源
- 更新getChatRecords等API方法使用ThreadLocal模式替代原有的acquire/release机制
- 修复多线程并发时的double-free问题,改进资源管理的安全性
- 优化文件分片下载的流处理,使用try-with-resources避免资源泄漏
- 标记旧的SDK管理方法为@deprecated,提供向后兼容性保证
- 移除了关于暴露 SDK 的废弃方法注释
- 删除了推荐使用 getChatRecords 的废弃提示
- 简化了方法文档,保留核心功能说明
- 添加废弃说明提醒用户使用新版本文档
- 指引用户迁移到CP_MSG_AUDIT_THREADLOCAL_LIFECYCLE_REFACTOR.md
- 修正了关于Finance.DestroySdk()自动执行的错误描述
- 明确了无论线程池还是独立线程都需要显式调用closeThreadLocalSdk()
- 强调了native资源泄漏的风险和预防措施
- 更新了测试代码中的注释说明
- 完善了注意事项中的线程安全相关描述
- 在获取失效SDK句柄时抛出WxErrorException异常
- 添加详细的错误信息提示调用closeAllSdks方法
- 确保线程安全的SDK句柄管理机制
- 修改线程安全警告信息,从重新初始化改为检查调用逻辑
- 移除失效SDK句柄后抛出异常提示检查closeAllSdks调用
- 简化了无效SDK句柄的处理流程
- 统一了异常抛出逻辑的代码结构
- 移除了不必要的else分支提高代码可读性
- 保持了原有的警告日志记录功能
- 维持了线程本地变量的清理操作
@OldQi
Copy link
Contributor Author

OldQi commented Mar 22, 2026

已处理review建议

@binarywang
Copy link
Owner

很多都还没有resolve 吧?

@OldQi
Copy link
Contributor Author

OldQi commented Mar 22, 2026

ok,resolve 了,以为改了代码的你这边点resolve

@binarywang binarywang merged commit 7089548 into binarywang:develop Mar 22, 2026
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.

3 participants