@@ -65,7 +65,18 @@ Either rename the directory at `temp_dir` to `new_path` and set it to read-only
6565or if `new_path` artifact already exists try to do nothing.
6666"""
6767function _mv_temp_artifact_dir (temp_dir:: String , new_path:: String ):: Nothing
68- if ! isdir (new_path)
68+ # Sometimes a rename can fail because the temp_dir is locked by
69+ # anti-virus software scanning the new files.
70+ # In this case we want to sleep and try again.
71+ # I am using the list of error codes to retry from:
72+ # https://github.com/isaacs/node-graceful-fs/blob/234379906b7d2f4c9cfeb412d2516f42b0fb4953/polyfills.js#L87
73+ # Retry for up to about 60 seconds by retrying 20 times with exponential backoff.
74+ retry = 0
75+ max_num_retries = 20 # maybe this should be configurable?
76+ sleep_amount = 0.01 # seconds
77+ max_sleep_amount = 5.0 # seconds
78+ while true
79+ isdir (new_path) && return
6980 # This next step is like
7081 # `mv(temp_dir, new_path)`.
7182 # However, `mv` defaults to `cp` if `rename` returns an error.
@@ -75,14 +86,19 @@ function _mv_temp_artifact_dir(temp_dir::String, new_path::String)::Nothing
7586 # rename worked
7687 chmod (new_path, filemode (dirname (new_path)))
7788 set_readonly (new_path)
89+ return
7890 else
79- # Ignore rename error, if `new_path` exists.
80- if ! isdir (new_path)
91+ # Ignore rename error if `new_path` exists.
92+ isdir (new_path) && return
93+ if retry < max_num_retries && err ∈ (Base. UV_EACCES, Base. UV_EPERM, Base. UV_EBUSY)
94+ sleep (sleep_amount)
95+ sleep_amount = min (sleep_amount* 2.0 , max_sleep_amount)
96+ retry += 1
97+ else
8198 Base. uv_error (" rename of $(repr (temp_dir)) to $(repr (new_path)) " , err)
8299 end
83100 end
84101 end
85- nothing
86102end
87103
88104"""
0 commit comments