fix: 修复会话存档SDK生命周期管理的审查问题
1. getChatRecords() 返回空列表而非 null,避免 NPE 2. downloadMediaFile() 正确传播文件写入异常 3. updateMsgAuditSdk() 确保旧 SDK 被销毁,避免资源泄漏
This commit is contained in:
@@ -20,6 +20,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@@ -345,7 +346,8 @@ public class WxCpMsgAuditServiceImpl implements WxCpMsgAuditService {
|
||||
throw new WxErrorException(chatDatas.toJson());
|
||||
}
|
||||
|
||||
return chatDatas.getChatData();
|
||||
List<WxCpChatDatas.WxCpChatData> chatDataList = chatDatas.getChatData();
|
||||
return chatDataList != null ? chatDataList : Collections.emptyList();
|
||||
} finally {
|
||||
// 释放SDK引用计数(原子操作)
|
||||
this.releaseSdk(sdk);
|
||||
@@ -392,21 +394,34 @@ public class WxCpMsgAuditServiceImpl implements WxCpMsgAuditService {
|
||||
throw new WxErrorException(e);
|
||||
}
|
||||
|
||||
// 使用AtomicReference捕获Lambda中的异常,以便在执行完后抛出
|
||||
final java.util.concurrent.atomic.AtomicReference<Exception> exceptionHolder = new java.util.concurrent.atomic.AtomicReference<>();
|
||||
|
||||
try {
|
||||
File targetFile = new File(targetFilePath);
|
||||
if (!targetFile.getParentFile().exists()) {
|
||||
targetFile.getParentFile().mkdirs();
|
||||
}
|
||||
this.getMediaFile(sdk, sdkfileid, proxy, passwd, timeout, i -> {
|
||||
// 如果之前已经发生异常,不再继续处理
|
||||
if (exceptionHolder.get() != null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// 大于512k的文件会分片拉取,此处需要使用追加写,避免后面的分片覆盖之前的数据。
|
||||
FileOutputStream outputStream = new FileOutputStream(targetFile, true);
|
||||
outputStream.write(i);
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
exceptionHolder.set(e);
|
||||
}
|
||||
});
|
||||
|
||||
// 检查是否发生异常,如果有则抛出
|
||||
Exception caughtException = exceptionHolder.get();
|
||||
if (caughtException != null) {
|
||||
throw new WxErrorException(caughtException);
|
||||
}
|
||||
} finally {
|
||||
// 释放SDK引用计数(原子操作)
|
||||
this.releaseSdk(sdk);
|
||||
|
||||
@@ -475,14 +475,16 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
|
||||
|
||||
@Override
|
||||
public synchronized void updateMsgAuditSdk(long sdk, int expiresInSeconds) {
|
||||
// 如果有旧的SDK且引用计数为0,先销毁旧的SDK
|
||||
if (this.msgAuditSdk > 0 && this.msgAuditSdk != sdk && this.msgAuditSdkRefCount == 0) {
|
||||
// 如果有旧的SDK且不同于新的SDK,需要销毁旧的SDK
|
||||
if (this.msgAuditSdk > 0 && this.msgAuditSdk != sdk) {
|
||||
// 无论旧SDK是否仍有引用,都需要销毁它以避免资源泄漏
|
||||
// 如果有飞行中的请求使用旧SDK,这些请求可能会失败,但这比资源泄漏更安全
|
||||
Finance.DestroySdk(this.msgAuditSdk);
|
||||
}
|
||||
this.msgAuditSdk = sdk;
|
||||
// 预留200秒的时间
|
||||
this.msgAuditSdkExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
|
||||
// 重置引用计数
|
||||
// 重置引用计数,因为这是一个全新的SDK
|
||||
this.msgAuditSdkRefCount = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -493,14 +493,16 @@ public class WxCpRedisConfigImpl implements WxCpConfigStorage {
|
||||
|
||||
@Override
|
||||
public synchronized void updateMsgAuditSdk(long sdk, int expiresInSeconds) {
|
||||
// 如果有旧的SDK且引用计数为0,先销毁旧的SDK
|
||||
if (this.msgAuditSdk > 0 && this.msgAuditSdk != sdk && this.msgAuditSdkRefCount == 0) {
|
||||
// 如果有旧的SDK且不同于新的SDK,需要销毁旧的SDK
|
||||
if (this.msgAuditSdk > 0 && this.msgAuditSdk != sdk) {
|
||||
// 无论旧SDK是否仍有引用,都需要销毁它以避免资源泄漏
|
||||
// 如果有飞行中的请求使用旧SDK,这些请求可能会失败,但这比资源泄漏更安全
|
||||
Finance.DestroySdk(this.msgAuditSdk);
|
||||
}
|
||||
this.msgAuditSdk = sdk;
|
||||
// 预留200秒的时间
|
||||
this.msgAuditSdkExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
|
||||
// 重置引用计数
|
||||
// 重置引用计数,因为这是一个全新的SDK
|
||||
this.msgAuditSdkRefCount = 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user