feat(settings): configure transfer failure aggregation

This commit is contained in:
jxxghp
2026-08-22 11:46:41 +08:00
parent 19e8e06798
commit 95bdeb6ebf
5 changed files with 31 additions and 2 deletions
+3
View File
@@ -2276,6 +2276,9 @@ export default {
transferMaxFailedRetries: 'Transfer Retries on Failure',
transferMaxFailedRetriesHint:
'Maximum automatic retries after a failed transfer, so a transient network or recognition glitch cannot permanently skip a file. Once exhausted, transfer it manually or delete the transfer history. Range 1-10; the counter resets on a successful transfer or when the record is deleted. Takes effect immediately after saving.',
transferFailureNotificationAggregation: 'Aggregate Transfer Failure Notifications by Media',
transferFailureNotificationAggregationHint:
'Combine transfer failures for the same media and season within a short window, including the failure count, reason summary, and a batch-processing link. Disable to send one notification per file.',
fsProxyEnabled: 'Isolate Local File Operations',
fsProxyEnabledHint:
'Run local file reads, copies, moves and deletes in a separate subprocess. When a FUSE mount such as CloudDrive2 stops responding, these calls hang forever and cannot be interrupted, which in turn stalls the transfer queue and directory monitoring. Isolated, they can be force-reclaimed after a timeout and surface as ordinary errors that the existing retry logic handles. Disable to fall back to direct calls, matching the previous behaviour.',
+3
View File
@@ -2237,6 +2237,9 @@ export default {
transferMaxFailedRetries: '整理失败重试次数',
transferMaxFailedRetriesHint:
'自动整理失败后允许重试的最大次数,避免一次网络或识别抖动让文件永久漏整理;次数用尽后需手动整理或删除整理记录。取值 1-10,整理成功或删除记录时计数清零,保存后即时生效',
transferFailureNotificationAggregation: '按媒体聚合整理失败通知',
transferFailureNotificationAggregationHint:
'开启后,同一媒体同一季在短时间内产生的整理失败会合并发送,并展示失败数量、原因统计和批量处理入口;关闭时逐条发送',
fsProxyEnabled: '本地文件操作隔离',
fsProxyEnabledHint:
'在独立子进程中执行本地文件的读取、复制、移动与删除。CloudDrive2 等 FUSE 挂载失去响应时,这类操作会永久卡住且无法中断,进而拖死整理队列与目录监控;隔离后可在超时后强制回收并转为普通错误,由既有的重试机制接管。关闭后退回直接调用,行为与旧版一致',
+3
View File
@@ -2236,6 +2236,9 @@ export default {
transferMaxFailedRetries: '整理失敗重試次數',
transferMaxFailedRetriesHint:
'自動整理失敗後允許重試的最大次數,避免一次網路或辨識抖動讓檔案永久漏整理;次數用盡後需手動整理或刪除整理記錄。取值 1-10,整理成功或刪除記錄時計數歸零,保存後即時生效',
transferFailureNotificationAggregation: '按媒體聚合整理失敗通知',
transferFailureNotificationAggregationHint:
'開啟後,同一媒體同一季在短時間內產生的整理失敗會合併發送,並顯示失敗數量、原因統計和批量處理入口;關閉時逐條發送',
fsProxyEnabled: '本機檔案操作隔離',
fsProxyEnabledHint:
'在獨立子行程中執行本機檔案的讀取、複製、移動與刪除。CloudDrive2 等 FUSE 掛載失去回應時,這類操作會永久卡住且無法中斷,進而拖死整理佇列與目錄監控;隔離後可在逾時後強制回收並轉為一般錯誤,由既有的重試機制接手。關閉後退回直接呼叫,行為與舊版一致',
@@ -145,6 +145,7 @@ const SystemSettings = ref<any>({
TRANSFER_THREADS: 1,
MONITOR_NETWORK_FAST_MODE: false,
TRANSFER_MAX_FAILED_RETRIES: 3,
TRANSFER_FAILURE_NOTIFICATION_AGGREGATION: false,
FS_PROXY_ENABLED: true,
FS_PROXY_TIMEOUT: 30,
FS_PROXY_STALL_TIMEOUT: 120,
@@ -2712,6 +2713,14 @@ watch(currentLlmSnapshotKey, (snapshotKey, previousSnapshotKey) => {
prepend-inner-icon="mdi-refresh-alert"
/>
</VCol>
<VCol cols="12" md="6">
<VSwitch
v-model="SystemSettings.Advanced.TRANSFER_FAILURE_NOTIFICATION_AGGREGATION"
:label="t('setting.system.transferFailureNotificationAggregation')"
:hint="t('setting.system.transferFailureNotificationAggregationHint')"
persistent-hint
/>
</VCol>
<VCol v-if="SystemSettings.Advanced.FS_PROXY_ENABLED" cols="12" md="6">
<VTextField
v-model.number="SystemSettings.Advanced.FS_PROXY_TIMEOUT"
@@ -1194,7 +1194,10 @@ describe('AccountSettingSystem', () => {
})
it('round-trips every advanced laboratory control when Rust is available', async () => {
systemEnv.RUST_ACCEL_AVAILABLE = true
Object.assign(systemEnv, {
RUST_ACCEL_AVAILABLE: true,
TRANSFER_FAILURE_NOTIFICATION_AGGREGATION: true,
})
await renderSettings()
const dialog = await openAdvancedTab('实验室')
await fireEvent.update(dialog.getByLabelText('本地插件仓库路径'), '/plugins/local')
@@ -1202,7 +1205,14 @@ describe('AccountSettingSystem', () => {
await fireEvent.update(dialog.getByLabelText('整理失败重试次数'), '6')
await fireEvent.update(dialog.getByLabelText('文件操作超时(秒)'), '45')
await fireEvent.update(dialog.getByLabelText('文件复制停滞超时(秒)'), '180')
for (const label of ['插件热加载', '本地文件操作隔离', '编码探测性能模式', 'Rust 加速', '网络存储快速监控']) {
for (const label of [
'插件热加载',
'按媒体聚合整理失败通知',
'本地文件操作隔离',
'编码探测性能模式',
'Rust 加速',
'网络存储快速监控',
]) {
await fireEvent.click(dialog.getByLabelText(label))
}
await fireEvent.click(dialog.getByRole('button', { name: '保存' }))
@@ -1218,6 +1228,7 @@ describe('AccountSettingSystem', () => {
PLUGIN_AUTO_RELOAD: true,
PLUGIN_LOCAL_REPO_PATHS: '/plugins/local',
RUST_ACCEL: true,
TRANSFER_FAILURE_NOTIFICATION_AGGREGATION: false,
TRANSFER_MAX_FAILED_RETRIES: 6,
TRANSFER_THREADS: 4,
}),