diff --git a/Project.toml b/Project.toml index 4c26018..3a9fba8 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "SweepRunner" uuid = "be946ad2-3cb3-4b6e-8f7e-4a5ecc3c255b" -version = "0.6.4" +version = "0.6.5" authors = ["sota shimozono "] [deps] @@ -19,11 +19,12 @@ TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" [compat] Aqua = "0.8" -# 0.8.2 is the floor, not a preference: `artifact!` / `ArtifactBusy` (what the deferral and -# `artifact_affinity` are built for) arrived there. The owner-stamped `.running` API -# (`new_owner_token`, `running_owner`, and the three-argument `refresh_running!` / +# 0.8.3 is the floor, not a preference: `save!` returning the digest it wrote, and +# `mark_done!(…; result)` that puts it in `.done`, arrived there. `artifact!` / `ArtifactBusy` +# (what the deferral and `artifact_affinity` are built for) came in 0.8.2. The owner-stamped +# `.running` API (`new_owner_token`, `running_owner`, and the three-argument `refresh_running!` / # `clear_running!`) that the liveness reaper is built on arrived in 0.8.1. -DataVault = "0.8.2" +DataVault = "0.8.3" Dates = "1.11" Distributed = "1.11" JLD2 = "0.6" diff --git a/src/Run.jl b/src/Run.jl index 2191f8b..703f853 100644 --- a/src/Run.jl +++ b/src/Run.jl @@ -795,10 +795,18 @@ function _run_one_with_retry!( log_event(log, :lock_lost; stage=stage, key=kstr, attempt=attempt) return :lock_busy end - DataVault.save!(vault, key, payload) - DataVault.mark_done!(vault, key) + # The digest save! took before its rename goes into the marker, so `.done` names the + # bytes this attempt wrote rather than whatever the file holds when someone looks. + saved = DataVault.save!(vault, key, payload) + DataVault.mark_done!(vault, key; result=saved) log_event( - log, :key_done; stage=stage, key=kstr, secs=time() - t0, attempt=attempt + log, + :key_done; + stage=stage, + key=kstr, + secs=time() - t0, + attempt=attempt, + sha256=saved.sha256, ) return :ok catch e diff --git a/test/run/test_run_result_digest.jl b/test/run/test_run_result_digest.jl new file mode 100644 index 0000000..e8912cf --- /dev/null +++ b/test/run/test_run_result_digest.jl @@ -0,0 +1,29 @@ +# The `.done` marker names the bytes run! wrote: the digest DataVault.save! took before its rename. + +using SweepRunner, Test, DataVault, ParamIO, SHA + +const _DIGEST_CFG = joinpath(@__DIR__, "fixtures", "study.toml") + +function _done_fields(v, key) + pairs = (split(l, '='; limit=2) for l in eachline(DataVault._done_file(v, key))) + return Dict(String(p[1]) => String(p[2]) for p in pairs) +end + +@testset "run!: every .done names the digest of the file it wrote" begin + outdir = mktempdir() + try + v = DataVault.Vault(_DIGEST_CFG; run="digest", outdir=outdir) + keys = ParamIO.expand(v.spec) + res = run!(key -> Dict{String,Any}("N" => key.params["N"]), v, keys) + @test res.done == length(keys) + for key in keys + f = _done_fields(v, key) + @test f["done_version"] == "2" + @test f["result_sha256"] == + bytes2hex(open(sha256, DataVault._data_file(v, key))) + @test joinpath(outdir, f["result_file"]) == DataVault._data_file(v, key) + end + finally + rm(outdir; recursive=true, force=true) + end +end