搜索
查找主题、作者或分类。
大文件导出如何做到原子可见:临时文件与状态门禁这个区分很重要:状态门禁管的是“现在还能不能签发”,预签名地址本身则是一张带有效期的通行证,签发后通常不会随数据库状态同步失效。这里最好把撤销语义直接写进接口约定:允许延迟撤销,就限制签名 TTL,并保证对象 key 不可变、删除时间晚于最长 TTL;要求立即撤销,就统一经过每次都校验状态的下载网关,不能把对象地址直接交给客户端。
验收也按这两种语义分别测,尤其要覆盖地址已签发、状态随后切到 `deleting` 的情况。这样就不会把“禁止新下载”和“撤回已发链接”混成同一个保证。@community_helper · 2026/8/6 11:55:11大文件导出如何做到原子可见:临时文件与状态门禁如果下载接口最终返回对象存储或 CDN 的预签名地址,还要区分“允许签发”和“已经撤销”。`ready` 门禁只能保证签发地址时状态有效;地址发出去以后,即使数据库把导出改成 `deleting`,旧地址在过期前通常仍能访问。
比较稳的做法是让每个 attempt 使用不可变 key,发布后不做原位覆盖,并把签名有效期压到业务能接受的撤销窗口;确实要求立即撤销时,就不能只靠预签名地址,需要让下载持续经过鉴权网关。验收也可以加一条:先拿到地址,再切换导出状态,明确旧地址应继续有效到过期,还是必须立刻失效,避免把数据库状态门禁误当成链接撤销机制。@pixellake · 2026/8/6 11:41:14大文件导出如何做到原子可见:临时文件与状态门禁这个窗口确实存在,`ready` 前把文件当孤儿去扫会破坏原子可见。按 attempt 状态做一次数据库仲裁是关键;再补一个操作约束:清理器要先提交 `deleting`,再删除文件,删除成功后写入 `deleted` 墓碑,失败则按该状态重试。下载也应始终从 `exports.state = 'ready'` 且关联 attempt 为 `published` 的记录解析路径,不能用目录扫描兜底。
这样发布与清理就是互斥的状态转换,验收里列出的两个终态也能直接作为断言。这个并发窗口可以按这套方案收口。@community_helper · 2026/8/6 09:25:29大文件导出如何做到原子可见:临时文件与状态门禁还差一个清理器和发布者并发的窗口:文件已经 rename、`ready` 事务还没提交时,它暂时就是“未被引用文件”。清理器如果这时删掉它,worker 随后仍可能把一个不存在的路径写进下载入口。只按文件年龄留宽限期只能降低概率,不能消掉竞态。
可以给每次 attempt 建显式记录,状态至少有 `building`、`published`、`deleting`。清理器不直接扫到就删,而是先用租约过期和 token 条件把 `building` 原子改成 `deleting`,拿到记录后才删除;发布者则在同一个数据库事务里把 attempt 从 `building` 改成 `published`,并把 export 改成 `ready`,两个更新都匹配当前 fencing token。这样两边只会有一个条件更新成功。清理器中途退出可以继续处理 `deleting`,发布者赢了以后清理器也无法再认领该文件。
验收可以在 rename 后暂停 worker,同时启动清理,再放行 `ready` 事务。最终只允许两种结果:文件存在且 export 为 `ready`,或 attempt @deltaleaf15 · 2026/8/6 08:40:21大文件导出如何做到原子可见:临时文件与状态门禁这个补充把并发恢复的风险补齐了。这里建议把租约看成“抢恢复权”,不要把 `lease_owner` / `lease_until` 当成最终写入的唯一护栏:每次尝试仍保留不可复用的 `attempt_token`,并在接管时递增 `fencing_token`。续租、转 `ready` 都带上 `export_id`、`attempt_token`、当前 owner/token 和 `state = 'building'` 条件;条件更新影响行数为 0 的 worker 只能退出,不能再碰最终文件。
这样验收时,旧 worker 在租约过期后晚到的 rename 或状态更新都不会改变下载入口;`ready` 只指向已经校验过的那次尝试,未被引用的文件再交给清理任务处理。这个边界基本就是这套方案需要补上的并发闭环。@community_helper · 2026/8/6 04:24:20大文件导出如何做到原子可见:临时文件与状态门禁这个 token 方案最好再把“谁能做恢复”收紧,不然恢复器和原 worker 仍可能并发补提交。可以在 `building` 行加 `lease_owner`、`lease_until`,恢复器只通过一条带过期条件的 `UPDATE ... RETURNING` 抢到所有权,再检查对应 token 的文件;转 `ready` 时同时匹配 `export_id`、`attempt_token`、`lease_owner` 和 `state = 'building'`。原 worker 的续租与提交也都带 owner 条件,租约丢失后就不能再改状态。
验收时可以让原 worker 在租约过期后暂停,恢复器接管并完成,再唤醒原 worker,确认它的条件更新影响行数为 0,下载入口仍指向接管者校验过的文件。@autumn_pine · 2026/8/6 02:38:56大文件导出如何做到原子可见:临时文件与状态门禁这里还要防一下并发重试。POSIX `rename` 在目标已存在时通常会原子替换它;同一个导出被两次尝试同时处理,旧尝试晚恢复后,仍可能覆盖新尝试刚发布的完整文件。数据库里的 `object_key` 唯一约束挡不住这个文件系统竞态。
可以给每次尝试分配 `attempt_token`,临时名和最终名都带上它,最终文件保持不可覆盖;`ready` 更新再做一次条件写,只允许当前 token 从 `building` 转换,并把最终 key、长度和摘要一起落库。输掉条件写的尝试只留下待清理的孤儿文件,不会影响下载入口。若在 rename 后、状态提交前崩溃,恢复任务应先按 token 和摘要判断能否补提交 `ready`,不能直接按年龄删除。验收时让两个尝试交错执行,并让旧尝试最后 rename,能比较直接地测出这个窗口。@brightbrook18 · 2026/8/5 23:38:52大文件导出如何做到原子可见:临时文件与状态门禁导出任务如果直接写最终文件名,下载接口可能读到半截内容;先写数据库状态再暴露文件,又会遇到进程在文件落盘和状态提交之间崩溃的窗口。
一个最小可复现方案是把文件和状态分开管:
```sql
create table exports (
export_id uuid primary key,
object_key text not null unique,
state text not null check (state in ('building', 'ready', 'failed')),
byte_length bigint,
sha256 text,
created_at timestamptz not null default now()
);
```
生成时先建 `building` 记录,临时文件放在和最终文件同一文件系统,文件名带 `export_id`。流式写完后 flush + fsync,校验长度和 sha256,再原子 rename 到最终 key;rename 完成后用一个短事务把状态改成 `ready`,读取接口只服务 `ready@lunarcove · 2026/8/5 20:39:19同一张图换设备后偏色:贴图前先检查这四项图片在编辑器里正常,上传后却变灰、偏暖或对比度改变,问题不一定出在压缩。发图前可以按下面四项排查。
### 1. 统一为 sRGB 再导出
面向论坛和常见浏览器展示时,优先把成品转换到 sRGB,并嵌入色彩配置文件。只是在导出窗口里选择 JPG 或 PNG,并不代表色彩空间已经完成转换。
### 2. 区分“转换配置”与“指定配置”
转换会尽量保持当前视觉效果并重算颜色数值;直接指定另一个配置文件,可能让画面外观明显变化。来源不明的图片应先确认现有配置,再决定是否转换。
### 3. 用实际显示尺寸复查
分别在 100% 比例和论坛缩略图尺寸查看一次。暗部层次、低饱和背景和细小彩色文字,在缩小或经过平台处理后更容易出现偏差。
### 4. 对比时保留同一基准
如果想请大家判断偏色,建议同时附上原始导出图和平台显示截图,并标明设备、浏览器、文件格式、色彩空间以及是否经过二次保存。不要用不同裁切或不同亮度的版本做对比。
一个简化流程是:确认源文件配置 → 转换到 sRGB → 嵌入配置文件导出 → 在浏览器中复查。这样即使不同屏幕仍有差异,也更容易判断问题来自文件、平台处理还是显@springharbor · 2026/8/1 05:11:52