稳定组成这个文件优化
This commit is contained in:
4
app/.env
4
app/.env
@@ -11,9 +11,9 @@ zn_username=%E8%87%AA%E5%8A%A8%E5%8C%96_Robot
|
|||||||
client_name=ShuFuAI
|
client_name=ShuFuAI
|
||||||
|
|
||||||
|
|
||||||
# java_api_base=http://47.111.163.154:18080
|
java_api_base=http://47.111.163.154:18080
|
||||||
# java_api_base=http://127.0.0.1:18080
|
# java_api_base=http://127.0.0.1:18080
|
||||||
# java_api_base=http://8.136.19.173:18080
|
# java_api_base=http://8.136.19.173:18080
|
||||||
java_api_base=http://121.196.149.225:18080
|
# java_api_base=http://121.196.149.225:18080
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ public class AppearancePatentTaskService {
|
|||||||
private static final String STATUS_SUCCESS = "SUCCESS";
|
private static final String STATUS_SUCCESS = "SUCCESS";
|
||||||
private static final String STATUS_FAILED = "FAILED";
|
private static final String STATUS_FAILED = "FAILED";
|
||||||
private static final String CONTENT_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
private static final String CONTENT_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||||
|
private static final int RESULT_ROWS_READ_RETRY_LIMIT = 3;
|
||||||
|
private static final long RESULT_ROWS_READ_RETRY_DELAY_MS = 500L;
|
||||||
private static final List<String> RESULT_HEADERS = List.of(
|
private static final List<String> RESULT_HEADERS = List.of(
|
||||||
"id",
|
"id",
|
||||||
"asin",
|
"asin",
|
||||||
@@ -759,12 +761,17 @@ public class AppearancePatentTaskService {
|
|||||||
}
|
}
|
||||||
String payloadJson = writeJson(rows == null ? List.of() : rows, "结果序列化失败");
|
String payloadJson = writeJson(rows == null ? List.of() : rows, "结果序列化失败");
|
||||||
payloadJson = writeJson(new ArrayList<>(persistedRows.values()), "appearance patent chunk payload merge failed");
|
payloadJson = writeJson(new ArrayList<>(persistedRows.values()), "appearance patent chunk payload merge failed");
|
||||||
String storedPayload = transientPayloadStorageService.storeChunkPayload(MODULE_TYPE, taskId, scopeHash, chunkIndex, payloadJson);
|
String oldPayload = chunk.getPayloadJson();
|
||||||
transientPayloadStorageService.deleteReplacedPayloadIfNeeded(chunk.getPayloadJson(), storedPayload);
|
String storedPayload = transientPayloadStorageService.storeChunkPayloadVersioned(MODULE_TYPE, taskId, scopeHash, chunkIndex, payloadJson);
|
||||||
chunk.setPayloadJson(storedPayload);
|
chunk.setPayloadJson(storedPayload);
|
||||||
chunk.setPayloadHash(DigestUtil.sha256Hex(payloadJson));
|
chunk.setPayloadHash(DigestUtil.sha256Hex(payloadJson));
|
||||||
chunk.setUpdatedAt(LocalDateTime.now());
|
chunk.setUpdatedAt(LocalDateTime.now());
|
||||||
taskChunkMapper.updateById(chunk);
|
int updated = taskChunkMapper.updateById(chunk);
|
||||||
|
if (updated <= 0) {
|
||||||
|
transientPayloadStorageService.deletePayloadIfPresent(storedPayload);
|
||||||
|
throw new IllegalStateException("appearance patent chunk payload update failed");
|
||||||
|
}
|
||||||
|
transientPayloadStorageService.deleteReplacedPayloadIfNeeded(oldPayload, storedPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AppearancePatentResultRowDto> expandRows(List<AppearancePatentResultRowDto> representatives,
|
private List<AppearancePatentResultRowDto> expandRows(List<AppearancePatentResultRowDto> representatives,
|
||||||
@@ -1122,7 +1129,7 @@ public class AppearancePatentTaskService {
|
|||||||
|
|
||||||
private void assembleResultWorkbook(FileTaskEntity task, FileResultEntity result) {
|
private void assembleResultWorkbook(FileTaskEntity task, FileResultEntity result) {
|
||||||
AppearancePatentParsedPayloadDto parsed = readParsedPayload(task);
|
AppearancePatentParsedPayloadDto parsed = readParsedPayload(task);
|
||||||
Map<String, AppearancePatentResultRowDto> resultMap = loadPersistedResultRows(task.getId());
|
Map<String, AppearancePatentResultRowDto> resultMap = loadPersistedResultRowsWithRetry(task.getId(), parsed.getAllItems().size());
|
||||||
long resolvedRows = parsed.getAllItems().stream()
|
long resolvedRows = parsed.getAllItems().stream()
|
||||||
.filter(row -> findResultRow(row, resultMap) != null || findResultRowByAsin(row.getAsin(), resultMap) != null)
|
.filter(row -> findResultRow(row, resultMap) != null || findResultRowByAsin(row.getAsin(), resultMap) != null)
|
||||||
.count();
|
.count();
|
||||||
@@ -1131,6 +1138,9 @@ public class AppearancePatentTaskService {
|
|||||||
.count();
|
.count();
|
||||||
log.info("[appearance-patent] assemble workbook taskId={} parsedRows={} resultRows={} resolvedRows={} reasonRows={}",
|
log.info("[appearance-patent] assemble workbook taskId={} parsedRows={} resultRows={} resolvedRows={} reasonRows={}",
|
||||||
task.getId(), parsed.getAllItems().size(), resultMap.size(), resolvedRows, reasonRows);
|
task.getId(), parsed.getAllItems().size(), resultMap.size(), resolvedRows, reasonRows);
|
||||||
|
if (!parsed.getAllItems().isEmpty() && resultMap.isEmpty()) {
|
||||||
|
throw new BusinessException("外观专利检测结果为空,请稍后重试生成结果文件");
|
||||||
|
}
|
||||||
File outputDir = new File(storageProperties.getLocalTempDir(), "appearance-patent-result");
|
File outputDir = new File(storageProperties.getLocalTempDir(), "appearance-patent-result");
|
||||||
if (!outputDir.exists() && !outputDir.mkdirs()) {
|
if (!outputDir.exists() && !outputDir.mkdirs()) {
|
||||||
throw new BusinessException("创建结果目录失败");
|
throw new BusinessException("创建结果目录失败");
|
||||||
@@ -1164,6 +1174,33 @@ public class AppearancePatentTaskService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, AppearancePatentResultRowDto> loadPersistedResultRowsWithRetry(Long taskId, int expectedParsedRows) {
|
||||||
|
Map<String, AppearancePatentResultRowDto> result = loadPersistedResultRows(taskId);
|
||||||
|
if (expectedParsedRows <= 0 || !result.isEmpty()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (int attempt = 1; attempt <= RESULT_ROWS_READ_RETRY_LIMIT && result.isEmpty(); attempt++) {
|
||||||
|
sleepBeforeResultRowsRetry(attempt);
|
||||||
|
result = loadPersistedResultRows(taskId);
|
||||||
|
if (!result.isEmpty()) {
|
||||||
|
log.info("[appearance-patent] result rows recovered after retry taskId={} attempt={} rows={}",
|
||||||
|
taskId, attempt, result.size());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
log.warn("[appearance-patent] result rows still empty after retry taskId={} attempt={}/{}",
|
||||||
|
taskId, attempt, RESULT_ROWS_READ_RETRY_LIMIT);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sleepBeforeResultRowsRetry(int attempt) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(RESULT_ROWS_READ_RETRY_DELAY_MS * attempt);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void writeResultWorkbook(File xlsx, AppearancePatentParsedPayloadDto parsed, Map<String, AppearancePatentResultRowDto> resultMap) {
|
private void writeResultWorkbook(File xlsx, AppearancePatentParsedPayloadDto parsed, Map<String, AppearancePatentResultRowDto> resultMap) {
|
||||||
try (SXSSFWorkbook workbook = new SXSSFWorkbook(200); FileOutputStream fos = new FileOutputStream(xlsx)) {
|
try (SXSSFWorkbook workbook = new SXSSFWorkbook(200); FileOutputStream fos = new FileOutputStream(xlsx)) {
|
||||||
Sheet sheet = workbook.createSheet("外观专利检测结果");
|
Sheet sheet = workbook.createSheet("外观专利检测结果");
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ public class TransientPayloadStorageService {
|
|||||||
return store("task-chunk", moduleType, taskId, scopeHash, entryKey, content, true);
|
return store("task-chunk", moduleType, taskId, scopeHash, entryKey, content, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String storeChunkPayloadVersioned(String moduleType, Long taskId, String scopeHash, Integer chunkIndex, String content) {
|
||||||
|
String entryKey = chunkIndex == null
|
||||||
|
? UUID.randomUUID().toString()
|
||||||
|
: "chunk-" + chunkIndex + "-" + UUID.randomUUID();
|
||||||
|
return store("task-chunk", moduleType, taskId, scopeHash, entryKey, content, true);
|
||||||
|
}
|
||||||
|
|
||||||
public String resolvePayload(String value, String errorMessage) {
|
public String resolvePayload(String value, String errorMessage) {
|
||||||
String pointer = extractPointer(value);
|
String pointer = extractPointer(value);
|
||||||
if (pointer == null) {
|
if (pointer == null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user