fix(media): 清理旧 rendition 并确保失败状态落库
This commit is contained in:
1 parent
5d1a157085
commit
91b621fe75
9 files changed
+226
-35
No files matched your search
+4
-10
@@ -27,18 +27,12 @@ public class ThumbnailRecordService {
|
||||
if (episodeId == null || episodeId <= 0) {
|
||||
return;
|
||||
}
|
||||
MediaThumbnail existing = mediaThumbnailMapper.selectOne(
|
||||
Wrappers.<MediaThumbnail>lambdaQuery()
|
||||
.eq(MediaThumbnail::getEpisodeId, episodeId)
|
||||
.last("limit 1"));
|
||||
thumbnail.setDramaId(task.getDramaId() == null ? 0L : task.getDramaId());
|
||||
thumbnail.setEpisodeId(episodeId);
|
||||
thumbnail.setErrorMsg(TranscodeErrorTruncator.truncate(thumbnail.getErrorMsg()));
|
||||
if (existing == null) {
|
||||
mediaThumbnailMapper.insert(thumbnail);
|
||||
return;
|
||||
}
|
||||
thumbnail.setId(existing.getId());
|
||||
mediaThumbnailMapper.updateById(thumbnail);
|
||||
thumbnail.setId(null);
|
||||
mediaThumbnailMapper.delete(Wrappers.<MediaThumbnail>lambdaQuery()
|
||||
.eq(MediaThumbnail::getEpisodeId, episodeId));
|
||||
mediaThumbnailMapper.insert(thumbnail);
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -7,7 +7,7 @@ public final class TranscodeErrorTruncator {
|
||||
|
||||
public static final int MAX_ERROR_CHARS = 500;
|
||||
private static final String EMPTY = "";
|
||||
private static final String TRUNCATED_TEMPLATE = "…(truncated, total=%d chars)";
|
||||
private static final String TRUNCATED_TEMPLATE = "…(truncated, total=%d chars)…";
|
||||
|
||||
private TranscodeErrorTruncator() {
|
||||
}
|
||||
@@ -17,7 +17,10 @@ public final class TranscodeErrorTruncator {
|
||||
return message == null ? EMPTY : message;
|
||||
}
|
||||
String suffix = String.format(TRUNCATED_TEMPLATE, message.length());
|
||||
int prefixLength = Math.max(0, MAX_ERROR_CHARS - suffix.length());
|
||||
return message.substring(0, prefixLength) + suffix;
|
||||
int remain = Math.max(0, MAX_ERROR_CHARS - suffix.length());
|
||||
int prefixLength = remain / 2;
|
||||
int tailLength = remain - prefixLength;
|
||||
return message.substring(0, prefixLength)
|
||||
+ suffix + message.substring(message.length() - tailLength);
|
||||
}
|
||||
}
|
||||
+26
-2
@@ -217,8 +217,15 @@ public class TranscodeService {
|
||||
public void succeed(Long taskId, List<MediaRendition> renditions,
|
||||
MediaThumbnail thumbnail) {
|
||||
TranscodeTask task = getExisting(taskId);
|
||||
mediaRenditionMapper.delete(Wrappers.<MediaRendition>lambdaQuery()
|
||||
.eq(MediaRendition::getMediaAssetId, task.getMediaAssetId()));
|
||||
var renditionDelete = Wrappers.<MediaRendition>lambdaQuery();
|
||||
if (task.getEpisodeId() != null && task.getEpisodeId() > 0) {
|
||||
renditionDelete.and(wrapper -> wrapper
|
||||
.eq(MediaRendition::getMediaAssetId, task.getMediaAssetId())
|
||||
.or().eq(MediaRendition::getEpisodeId, task.getEpisodeId()));
|
||||
} else {
|
||||
renditionDelete.eq(MediaRendition::getMediaAssetId, task.getMediaAssetId());
|
||||
}
|
||||
mediaRenditionMapper.delete(renditionDelete);
|
||||
for (MediaRendition rendition : renditions) {
|
||||
rendition.setMediaAssetId(task.getMediaAssetId());
|
||||
rendition.setDramaId(task.getDramaId());
|
||||
@@ -277,6 +284,23 @@ public class TranscodeService {
|
||||
.set(TranscodeTask::getProgress, safeProgress));
|
||||
}
|
||||
|
||||
/** 主流程异常时立即终止任务,保留最后进度并写入截断后的错误。 */
|
||||
public int failFinal(Long taskId, String errorMessage) {
|
||||
if (taskId == null) {
|
||||
return 0;
|
||||
}
|
||||
int updated = transcodeTaskMapper.update(null, Wrappers.<TranscodeTask>lambdaUpdate()
|
||||
.eq(TranscodeTask::getId, taskId)
|
||||
.set(TranscodeTask::getStatus, STATUS_FAILED)
|
||||
.set(TranscodeTask::getErrorMsg,
|
||||
TranscodeErrorTruncator.truncate(errorMessage))
|
||||
.set(TranscodeTask::getFinishedAt, LocalDateTime.now()));
|
||||
if (updated == 0) {
|
||||
log.error("转码任务失败状态落库失败:task={} 不存在或未更新", taskId);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/** RUNNING 超过阈值且 updated_at 长期未变时自动收口,避免僵尸任务永久占位。 */
|
||||
public int recoverStaleRunningTasks() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
+16
-8
@@ -116,15 +116,23 @@ public class TranscodeWorker {
|
||||
logThumbnailResult(result.thumbnail());
|
||||
} catch (Exception ex) {
|
||||
String reason = ex.getMessage() == null ? ex.getClass().getSimpleName() : ex.getMessage();
|
||||
int attempt = (task.getRetryCount() == null ? 0 : task.getRetryCount()) + 1;
|
||||
String status = transcodeService.fail(task.getId(), reason);
|
||||
if (TranscodeService.STATUS_FAILED.equals(status)
|
||||
&& task.getMediaAssetId() != null && task.getMediaAssetId() > 0) {
|
||||
mediaService.markFailed(task.getMediaAssetId(), reason);
|
||||
try {
|
||||
transcodeService.failFinal(task.getId(), reason);
|
||||
} catch (Exception persistError) {
|
||||
log.error("转码任务失败状态落库失败 task={} 原因={}",
|
||||
task.getId(), persistError.getMessage(), persistError);
|
||||
}
|
||||
log.error("转码失败 task={} 第 {}/{} 次尝试 耗时={}ms 结果={} 原因={}",
|
||||
task.getId(), attempt, TranscodeService.MAX_RETRY, System.currentTimeMillis() - startedAt,
|
||||
status, reason);
|
||||
if (task.getMediaAssetId() != null && task.getMediaAssetId() > 0) {
|
||||
try {
|
||||
mediaService.markFailed(task.getMediaAssetId(), reason);
|
||||
} catch (Exception mediaError) {
|
||||
log.error("媒资失败状态落库失败 asset={} 原因={}",
|
||||
task.getMediaAssetId(), mediaError.getMessage(), mediaError);
|
||||
}
|
||||
}
|
||||
log.error("转码失败 task={} 耗时={}ms 结果=FAILED 原因={}",
|
||||
task.getId(), System.currentTimeMillis() - startedAt,
|
||||
TranscodeErrorTruncator.truncate(reason));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user