跳至正文

文件、副本与任务状态机 ​

修改上传、后台任务或删除流程时,需要同时检查文件、副本与任务的状态。本页说明三者的转移条件和最终结果;界面操作见图片管理,请求格式见 HTTP API。

模型概览 ​

对象职责状态数量
文件记录上传是否发布、是否允许公开访问、是否进入整图删除7
副本记录一个存储实例上的写入、删除与管理生命周期8
任务记录一项工作是否等待、执行、成功、失败或取消5

一个文件可以有多个副本,同一文件在同一存储实例最多有一条副本记录。写入和删除任务关联一个副本,保存后任务关联文件与处理链。

文件 ready 表示允许公开访问,读取仍需选取 ready 副本;它不保证每个副本或任务都已成功。副本 deleted 表示结束管理,文件 deleted 表示整图删除流程结束,副本记录在图片仍被管理时保留;文件进入 deleted 后,清理临时内容与派生缓存,再自动清除图片、副本、任务、上传会话、分类关联和源清理明细,释放公开路径,不保留历史。这些状态不保证远端对象不存在。

文件状态机 ​

状态含义访问与后续工作
preparing上传已登记,尚未发布不公开;等待首份成功并通过发布校验
ready已发布允许公开访问;其余写入和保存后任务可继续
blocked已发布,但被保存后处理屏蔽不公开;保留管理员私密预览,其余写入可继续
failed本次上传未能发布不公开;等待后台转入整图删除
deleting已接受整图删除不公开;停止写入和保存后工作,清理全部副本
delete_failed整图删除的任务已停止,仍有未终结副本等待删除重试或人工标记为已删除
deleted全部副本已终结,相关任务已停止自动清理专属记录,不再执行文件任务

首次发布与上传失败 ​

核心上传处理开始时检查权限与额度并选择上传计划;分片在完成请求合并后进入此流程。此后不因权限、额度或配置版本变化重新裁决上传资格。首次发布在事务中确认文件仍为 preparing、至少一个副本为 ready,原子累计一次成功次数;有保存后步骤则创建一个 action 任务。实际依赖消失或存储失败仍按原有错误流程处理。

发布前所有目标的首轮写入均结束且没有成功副本时,上传直接失败,不等待自动重试。已有副本促成发布后,其他目标写入失败只影响对应副本,可以按任务规则继续重试。上传登记之前的失败可能没有文件、副本或任务记录。

导入直接建立 ready 文件和副本,不创建写入任务、不自动补齐副本,也不执行保存后处理。

屏蔽与删除 ​

保存后任务可以屏蔽或删除文件。后续步骤失败仍保留已接受的处置,因此文件可以为 blocked,同时保存后任务为 failed。解除屏蔽只恢复文件为 ready;处置的累计规则见保存后处理。

整图删除包括上传失败后的后台清理、用户删除、保存后删除和替换旧图:先持久化删除意图,停止公开访问,再清理副本。后台扫描到 failed 文件时,将其转为 deleting 并清除原上传错误,复用整图删除流程。仅对 deleting/delete_failed 文件判断整图是否终结:

当前条件文件结果
仍有 pending/running 任务等待任务停止
任务均停止,仍有非 deleted 副本delete_failed
任务均停止,副本全部为 deleteddeleted,随后清除专属记录

停止的任务可以是 success/failed/cancelled。

副本状态机 ​

状态含义
pending已登记目标,尚未开始写入
writing已开始写入,成功结果尚未提交
ready写入明确成功,或已有对象导入成功
write_failed未确认写入成功,包括准备失败、明确失败和结果不确定
delete_pending已登记删除意图,尚未开始删除
deleting已开始删除,成功结果尚未提交
delete_failed未确认删除成功,包括准备失败、明确失败和结果不确定
deleted管理生命周期已终结,不再读取、写入、删除或重试

写入与清理入口 ​

同一副本不同时执行写入和删除。转入删除时,先等待在途写入退出并保存结果,再取消仍为 pending/failed 的写入任务,保留成功任务。只有尚未开始写入的 pending 副本可以在取消后直接终结;write_failed 必须进入删除流程,此规则适用于失败上传清理、整图删除和单副本删除。

删除与定位 ​

删除直接调用插件 delete。成功或明确报告目标不存在时,副本与删除任务一起提交为 deleted/success;缺少必要定位、插件不可用或不支持删除时进入失败处理。

Local、S3、WebDAV、OpenList 使用成功写入或导入时保存的 locator。缺少定位时以不可重试错误结束本次删除,不退回存储键猜测目标,以免误删同键其他对象;之后可人工标记为已删除。插件接口见存储插件。

同一副本已有删除任务时,重复清理或后续整图删除沿用该任务,不新增任务或重置预算。删除任务已经失败时,须手动重试任务或将副本人工标记为已删除;将文件从 failed 改为 deleting 本身不会重新启动该任务。

单副本删除 ​

单副本删除用于 ready/blocked 文件。目标正在写入或有关联运行任务时拒绝操作;有其他 ready 副本时,只清理目标副本,文件保持原状态。

没有其他 ready 副本时,默认转入整图删除并清理全部副本。显式 includeLast:false 时保留图片并返回 LAST_REPLICA;其他副本即使正在重试,也不能算作可用副本。

任务状态机 ​

类型创建时机操作标识
write上传登记时,为每个目标创建任务 ID
action首次发布时,有保存后步骤则创建每个步骤使用 任务ID:步骤ID
delete副本清理需要调用远端删除时创建任务 ID

每个文件最多一个 action 任务;每个副本最多一个状态为 pending/running/failed 的存储任务。插件调用在数据库事务外执行,副本结果与任务结果在同一事务内提交。

状态含义
pending首次执行或重试已安排,等待到期领取
running已领取,正在准备、执行或提交结果
success本项工作成功,结果已提交
failed本轮自动尝试或单次手动尝试已停止
cancelled工作已撤销,不直接重试

副本失败不表示任务已经停止:自动重试期间可以是 write_failed + write.pending 或 delete_failed + delete.pending。历史任务记录自身的执行结果,不要求与文件、副本的当前状态相同。

领取与重试条件 ​

任务必须为到期的 pending,有并发空位,且文件未被当前清理流程隔离。文件或副本已终结时,不再领取对应任务。

类型允许领取时的文件状态手动重试还需满足
writepreparing 且 attempts = 0;或 ready/blocked副本为 write_failed、存储实例可用且有内容来源;文件须为 ready/blocked
actionready处理链与内容来源可用;重新执行整条链
deleteready/blocked/failed/deleting副本为 delete_failed、存储实例可用;无需上传内容

手动重试 delete_failed 文件的删除任务时,同一事务中将文件改回 deleting。写入、保存后处理、删除分别使用 writeConcurrency、postSaveConcurrency、deleteConcurrency,不共享或借用名额;降低上限只影响后续派发。

写入领取使用三个严格优先级:

  1. 文件为 preparing、没有 ready 副本,也没有已领取或运行中的写入。
  2. 文件为 preparing、没有 ready 副本,但已有写入被领取或运行。
  3. 其他符合执行条件的写入,包括已有成功副本后的剩余写入和发布后的写入重试。

每档内部按 next_run_at、created_at、任务 ID 升序选择。已准入但尚未将任务标记为 running 的写入也参与判断;只判断是否存在,不比较运行数量。已有 ready 副本但尚未发布时,剩余写入已经属于第三档。优先级只影响领取,不打断正在运行的任务,同一文件的多个目标仍可并发写入。

保存后处理与删除不分优先级,直接按 next_run_at、created_at、任务 ID 升序选择。各类重试遵守原有退避,以本次到期时间排队,不额外插队。写入不做轮转、等待时间加权或优先级提升,持续有前两档任务时,第三档可能长时间等待。

attempts 在领取时增加,准备阶段失败也消耗次数。自动重试要求错误允许重试、预算未耗尽,且当前不是单次手动尝试;保存后任务还要求累计处置仍为 pass。retryLimit 包含首次尝试,默认值及配置入口见设置参考;退避时间为 1000 × 2^attempts 毫秒。

手动重试只接受符合条件的 failed 任务,复用任务和操作标识,不清零次数,本次失败后停止。写入重试直接调用 write,删除重试直接调用 delete;重复写入可能产生多个远端对象,核心只管理已保存的定位。插件如何声明重试见错误、取消与并发。

取消与重启 ​

在途操作与晚到结果 ​

取消信号不等于调用已结束。实际调用退出前,继续持有其使用的内容和实例租约。

写入明确成功后,仍须保存定位和 success 任务结果;随后的取消或收尾异常不能把它改成可重试失败。文件已进入清理时,保存成功结果后安排删除,不能重新发布。发布前取消与发布事务竞争时,以先提交的文件状态为准:失败先提交则清理,发布先提交则保留发布结果。

重启恢复 ​

重启前恢复后
副本 writing/deleting分别转为 write_failed/delete_failed
任务 running,仍有自动预算且非手动尝试pending,立即到期,次数不清零
任务 running,预算耗尽或为手动尝试failed
运行任务恢复为 failed,但副本仍为 pending/delete_pending分别转为 write_failed/delete_failed
文件 preparingfailed,只清理,不重新发布
文件 ready/blocked状态保持,按领取条件继续工作
文件 delete_failed/deleted 或任务已停止不因重启开启新预算

恢复后的未发布文件已经为 failed,其等待写入任务会在清理中取消。分片上传会话独立处理:中断的 completing 会话在关联文件为 ready/blocked 时转为 completed,否则转为 failed。

临时内容 ​

temp_path 记录待保留的临时内容路径,释放后清空;内容是否存在以实际文件读取结果为准。文件为 preparing,或仍有等待、运行中的写入与保存后任务时保留内容;其余工作停止且在途使用退出后释放,删除任务不依赖上传内容。

手动重试需要重新写入时,可使用保留的临时内容,或从就绪副本取得内容;无可用来源则不能重试写入。派生缓存不承担原图持久化职责,其释放由缓存策略管理。

解除关联与终结清理 ​

管理员可以对整张图片、指定副本或源筛选范围选择解除关联:不获取插件租约、不调用远端存储,直接将目标副本设为 deleted,取消关联的 pending/failed 任务,保留尝试次数、错误和历史结果。整图解除关联同时将文件设为 deleted,执行同样的终结清理;仅处理一个源且仍有其他 ready 副本时,文件与公开链接继续可用。

按源或副本处理默认 includeLast:true,没有其他 ready 副本时处理整张图片及其他失败副本;false 跳过并返回 LAST_REPLICA。删除和解除关联通过现有任务调度与清理锁准入;文件仍在上传、副本写入中、关联任务运行或已被调度准入时返回可重试 BUSY,不覆盖运行状态。

保留的 terminate 接口语义更窄:只允许人工终结删除失败的副本,不改变其他非删除状态的文件。它不调用存储插件,不将原失败任务改写为成功,图片仍被管理时保留副本与任务记录。解除关联或人工终结后,已终结副本的原任务不能再重试。

源清理任务跟踪固定目标的管理结果,删除任务仍在自动退避重试时保持 running,全部相关任务停止后才记录失败;整图操作需等待整张图片终结。任务与快照持久化关系见数据访问与初始化。

删除存储实例要求没有配置引用、未终结副本和在途调用。删除只移除实例配置,保留文件、副本和任务,以及原 storage_instance_id。已终结副本和停止的失败任务不阻止实例删除。

历史查询允许实例配置不存在,详情显示“存储源已删除”和原标识;新建实例使用新标识,不自动接管旧历史。持久化关系见数据访问与初始化。

容量记账 ​

存储实例的 usedStorageBytes 按所有 status != deleted 的副本计算,每条按关联文件登记的字节大小计入一次;replicaCount 表示未终结副本数。

新副本登记时计入,执行和重试不重复加算。任务失败、取消或预算耗尽不释放容量,只有副本进入 deleted 才释放,包括取消未开始的写入、删除成功和人工标记为已删除。文件是否为 failed 不改变记账规则。

重复写入产生的额外对象不另建账目,人工标记为已删除也不核实远端实际释放空间,因此账面容量可能与远端实际占用不同。

典型结果对照 ​

下表假定现有自动尝试已经结束,且没有新增操作。

场景文件副本与任务
全部写入成功,无屏蔽或删除处置ready副本均 ready,写入任务均 success
至少一份发布,其余写入失败ready成功副本 ready;失败副本 write_failed,写入任务 failed
保存后处理已屏蔽,后续步骤失败blocked保存后任务 failed,已成功的副本保持 ready
上传失败,清理最终失败delete_failed存在 delete_failed 副本与失败删除任务
上传失败,剩余副本全部人工标记为已删除已清除图片及其专属关联记录全部清除
单副本删除失败,其他副本可用原 ready/blocked目标副本 delete_failed,删除任务 failed
整图删除停止,仍有未终结副本delete_failed等待删除重试或人工标记为已删除
整图删除成功已清除图片及其专属关联记录全部清除
整图删除中,剩余失败副本全部人工标记为已删除已清除图片及其专属关联记录全部清除

文档随 main 分支维护;部署与升级请核对产物版本及兼容说明。