@@ -50,24 +50,34 @@ pub fn download_cached(info: &DownloadInfo) -> Result<Vec<u8>> {
5050 . build ( )
5151 . map_err ( |e| BuildError :: Http ( e. to_string ( ) ) ) ?;
5252
53- // Try download with retries
54- let max_retries = 3 ;
53+ // Try download with retries using exponential backoff
54+ // Use more retries and longer delays to handle transient GitHub outages (504 errors)
55+ let max_retries = 5 ;
56+ let base_delay_secs = 10 ;
5557 let mut last_error = String :: new ( ) ;
5658
5759 for attempt in 1 ..=max_retries {
5860 if attempt > 1 {
61+ // Exponential backoff: 10s, 20s, 40s, 80s
62+ let delay_secs = base_delay_secs * ( 1 << ( attempt - 2 ) ) ;
5963 println ! (
60- "cargo:warning=Retry attempt {}/{} for {}" ,
61- attempt, max_retries, info. name
64+ "cargo:warning=Retry attempt {}/{} for {} (waiting {}s) " ,
65+ attempt, max_retries, info. name, delay_secs
6266 ) ;
63- // Wait a bit before retrying
64- std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 2 ) ) ;
67+ std:: thread:: sleep ( std:: time:: Duration :: from_secs ( delay_secs) ) ;
6568 }
6669
6770 match client. get ( & info. url ) . send ( ) {
6871 Ok ( response) => {
69- if !response. status ( ) . is_success ( ) {
70- last_error = format ! ( "Failed with status: {}" , response. status( ) ) ;
72+ let status = response. status ( ) ;
73+ if !status. is_success ( ) {
74+ last_error = format ! ( "Failed with status: {status}" ) ;
75+ // For server errors (5xx), always retry
76+ if status. is_server_error ( ) {
77+ println ! (
78+ "cargo:warning=Server error ({status}), will retry if attempts remain"
79+ ) ;
80+ }
7181 continue ;
7282 }
7383
0 commit comments