Skip to content

Commit 8b90ac7

Browse files
committed
feat(Cache): continue trying to download if the first repository had some errors (leanprover-community#34539)
For me, it happens occasionally when working on a mathlib PR that downloading from mathlib, just one file fails. (This is more likely when e.g. modifying a syntax linter, so all of mathlib has to be rebuilt, and the mathlib cache has no hits.) Right now, lake exe cache get then skips downloading files from my fork. This is not helpful; these cache files are the ones I would have liked to download. In such situations, I have to manually retry the command. Depending on my network, this can happen several times. This PR changes the cache to keep downloading from the second (or third, fourth, ...) repository. To prevent lots of wasted work, we only do so if the number of failed downloads is small (at most 10).
1 parent 8894c12 commit 8b90ac7

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

Cache/Requests.lean

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -374,39 +374,38 @@ def monitorCurl (args : Array String) (size : Nat)
374374
return s
375375

376376
/-- Call `curl` to download files from the server to `CACHEDIR` (`.cache`).
377-
Exit the process with exit code 1 if any files failed to download. -/
377+
Return the number of files which failed to download. -/
378378
def downloadFiles
379379
(repo : String) (hashMap : IO.ModuleHashMap)
380-
(forceDownload : Bool) (parallel : Bool) (warnOnMissing : Bool): IO Unit := do
380+
(forceDownload : Bool) (parallel : Bool) (warnOnMissing : Bool): IO Nat := do
381381
let hashMap ← if forceDownload then pure hashMap else hashMap.filterExists false
382+
if hashMap.isEmpty then IO.println "No files to download"; return 0
382383
let size := hashMap.size
383-
if size > 0 then
384-
IO.FS.createDirAll IO.CACHEDIR
385-
IO.println s!"Attempting to download {size} file(s) from {repo} cache"
386-
let failed ← if parallel then
387-
IO.FS.writeFile IO.CURLCFG (← mkGetConfigContent repo hashMap)
388-
let args := #["--request", "GET", "--parallel",
389-
-- commented as this creates a big slowdown on curl 8.13.0: "--fail",
390-
"--silent",
391-
"--retry", "5", -- there seem to be some intermittent failures
392-
"--write-out", "%{json}\n", "--config", IO.CURLCFG.toString]
393-
let {success, failed, done, ..} ←
394-
monitorCurl args size "Downloaded" "speed_download" (removeOnError := true)
395-
IO.FS.removeFile IO.CURLCFG
396-
if warnOnMissing && success + failed < done then
397-
IO.eprintln "Warning: some files were not found in the cache."
398-
IO.eprintln "This usually means that your local checkout of mathlib4 has diverged from upstream."
399-
IO.eprintln "If you push your commits to a branch of the mathlib4 repository, CI will build the oleans and they will be available later."
400-
IO.eprintln "Alternatively, if you already have pushed your commits to a branch, this may mean the CI build has failed part-way through building."
401-
pure failed
402-
else
403-
let r ← hashMap.foldM (init := []) fun acc _ hash => do
404-
pure <| (← IO.asTask do downloadFile repo hash) :: acc
405-
pure <| r.foldl (init := 0) fun f t => if let .ok true := t.get then f else f + 1
406-
if failed > 0 then
407-
IO.println s!"{failed} download(s) failed"
408-
IO.Process.exit 1
409-
else IO.println "No files to download"
384+
IO.FS.createDirAll IO.CACHEDIR
385+
IO.println s!"Attempting to download {size} file(s) from {repo} cache"
386+
let failed ← if parallel then
387+
IO.FS.writeFile IO.CURLCFG (← mkGetConfigContent repo hashMap)
388+
let args := #["--request", "GET", "--parallel",
389+
-- commented as this creates a big slowdown on curl 8.13.0: "--fail",
390+
"--silent",
391+
"--retry", "5", -- there seem to be some intermittent failures
392+
"--write-out", "%{json}\n", "--config", IO.CURLCFG.toString]
393+
let {success, failed, done, ..} ←
394+
monitorCurl args size "Downloaded" "speed_download" (removeOnError := true)
395+
IO.FS.removeFile IO.CURLCFG
396+
if warnOnMissing && success + failed < done then
397+
IO.eprintln "Warning: some files were not found in the cache."
398+
IO.eprintln "This usually means that your local checkout of mathlib4 has diverged from upstream."
399+
IO.eprintln "If you push your commits to a branch of the mathlib4 repository, CI will build the oleans and they will be available later."
400+
IO.eprintln "Alternatively, if you already have pushed your commits to a branch, this may mean the CI build has failed part-way through building."
401+
pure failed
402+
else
403+
let r ← hashMap.foldM (init := []) fun acc _ hash => do
404+
pure <| (← IO.asTask do downloadFile repo hash) :: acc
405+
pure <| r.foldl (init := 0) fun f t => if let .ok true := t.get then f else f + 1
406+
if failed > 0 then
407+
IO.println s!"{failed} download(s) failed"
408+
return failed
410409

411410
/-- Check if the project's `lean-toolchain` file matches mathlib's.
412411
Print and error and exit the process with error code 1 otherwise. -/
@@ -481,7 +480,8 @@ def getFiles
481480
getProofWidgets (← read).proofWidgetsBuildDir
482481

483482
if let some repo := repo? then
484-
downloadFiles repo hashMap forceDownload parallel (warnOnMissing := true)
483+
let failed ← downloadFiles repo hashMap forceDownload parallel (warnOnMissing := true)
484+
if failed > 0 then IO.Process.exit 1
485485
else
486486
let repoInfo ← getRemoteRepo (← read).mathlibDepPath
487487

@@ -494,8 +494,15 @@ def getFiles
494494
else
495495
[MATHLIBREPO, repoInfo.repo]
496496

497+
let mut failed : Nat := 0
497498
for h : i in [0:repos.length] do
498-
downloadFiles repos[i] hashMap forceDownload parallel (warnOnMissing := i = repos.length - 1)
499+
failed := ← (downloadFiles repos[i] hashMap forceDownload parallel (warnOnMissing := i = repos.length - 1))
500+
if failed > 10 then
501+
IO.println s!"Too many downloads failed; stopping the downloading"
502+
IO.Process.exit 1
503+
if failed > 0 then
504+
IO.println s!"Downloading {failed} files failed"
505+
IO.Process.exit 1
499506

500507
if decompress then
501508
IO.unpackCache hashMap forceUnpack

0 commit comments

Comments
 (0)