Skip to content

Commit 5fba927

Browse files
IanButterworthKristofferC
authored andcommitted
Make write_env_usage atomic (#2661)
Fixes #2633 (cherry picked from commit 5bbfef6)
1 parent c29f708 commit 5fba927

File tree

1 file changed

+43
-8
lines changed

1 file changed

+43
-8
lines changed

src/Types.jl

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -464,15 +464,50 @@ function write_env_usage(source_file::AbstractString, usage_filepath::AbstractSt
464464
# Ensure that log dir exists
465465
!ispath(logdir()) && mkpath(logdir())
466466

467-
# Generate entire entry as a string first
468-
entry = sprint() do io
469-
TOML.print(io, Dict(source_file => [Dict("time" => now())]))
470-
end
471-
472-
# Append entry to log file in one chunk
473467
usage_file = joinpath(logdir(), usage_filepath)
474-
open(usage_file, append=true) do io
475-
write(io, entry)
468+
timestamp = now()
469+
470+
## Atomically write usage file
471+
while true
472+
# read existing usage file
473+
usage = if isfile(usage_file)
474+
TOML.parsefile(usage_file)
475+
else
476+
Dict{String, Any}()
477+
end
478+
479+
# record new usage
480+
usage[source_file] = [Dict("time" => timestamp)]
481+
482+
# keep only latest usage info
483+
for k in keys(usage)
484+
times = map(d -> Dates.DateTime(d["time"]), usage[k])
485+
usage[k] = [Dict("time" => maximum(times))]
486+
end
487+
488+
# Write to a temp file in the same directory as the destination
489+
temp_usage_file = tempname(logdir())
490+
open(temp_usage_file, "w") do io
491+
TOML.print(io, usage, sorted=true)
492+
end
493+
494+
# Move the temp file into place, replacing the original
495+
mv(temp_usage_file, usage_file, force = true)
496+
497+
# Check that the new file has what we want in it
498+
new_usage = if isfile(usage_file)
499+
TOML.parsefile(usage_file)
500+
else
501+
Dict{String, Any}()
502+
end
503+
if haskey(new_usage, source_file)
504+
for e in new_usage[source_file]
505+
if Dates.DateTime(e["time"]) >= timestamp
506+
return
507+
end
508+
end
509+
end
510+
# If not, try again
476511
end
477512
end
478513

0 commit comments

Comments
 (0)