自动化交付

导出到一半掉电,如何避免交付半个文件

文件写到一半服务重启,下载链接却已经对用户开放。这类故障不是“文件偶尔打不开”这么简单,而是系统把未完成产物当成了正式结果。处理办法应围绕发布边界设计,而不只是给写入操作套一层异常捕获。

阅读文本 / Reading text
本文使用合成样本演示处理方法。代码已通过隔离环境中的示例检查;这不代表对所有真实文件或产品效果的保证。处理重要文件前,请保留原件,并按文中的边界与验收项复核。 文件写到一半服务重启,下载链接却已经对用户开放。这类故障不是“文件偶尔打不开”这么简单,而是系统把未完成产物当成了正式结果。处理办法应围绕发布边界设计,而不只是给写入操作套一层异常捕获。 先写临时文件,再替换正式入口 本地文件系统中,常用方式是在目标目录写临时文件,写完并关闭后再调用 os.replace 。同目录可以避免常见的跨文件系统替换问题。原子替换只描述读者看到哪个名字,并不等于断电后数据一定持久保存。 用状态计划说明发布顺序 下面不真的创建或覆盖文件,而是验证交付计划:只有写入、关闭和内容校验全部完成,才允许替换正式路径。真正的文件写入器还需处理异常清理、权限和平台差异。 def publish_plan(written, closed, content_ok, same_filesystem): if not written: return ("write_temporary",) if not closed: return ("close_temporary",) if not content_ok: return ("quarantine_temporary",) if not same_filesystem: return ("prepare_destination_temporary",) return ("replace_destination", "confirm_readable", "mark_ready") assert publish_plan(False, False, False, True) == ("write_temporary",) assert publish_plan(True, False, True, True) == ("close_temporary",) assert publish_plan(True, True, False, True) == ("quarantine_temporary",) assert "mark_ready" not in publish_plan(True, True, True, False) assert publish_plan(True, True, True, True)[-1] == "mark_ready" 这是协议测试,不是断电实验。若需要更强的持久性保证,还需研究文件与目录同步、磁盘和文件系统语义,并通过故障注入验证。不要把一次普通读写成功包装成“掉电安全已证明”。 哪些状态允许下载 产物状态 对外可见性 恢复动作 临时文件写入中 不提供正式链接 重试或清理残留 内容校验失败 隔离,不发布 保留排错信息 替换完成但未确认读取 暂不标记成功 检查最终路径 可读取且校验匹配 提供结果 记录版本与摘要 对象存储别硬套 rename 对象存储通常没有与本地文件系统完全相同的目录重命名语义。更适合采用不可变对象键,上传完成并验证后更新数据库中的正式指针。若还涉及 CDN,缓存键与旧版本保留也要一起考虑。 翻译完成应包含文件交付 把 OmniDoc(产品入口) 的处理状态接到自己的产品时,不能收到“处理结束”就立即显示本地下载成功。应确认你保存的译稿可以读取、类型正确,再把任务置为可交付。用户感知的完成,最终是拿到一份能打开的文件。 参考: Python tempfile 。 - 1 -
更新于 2026-10-08