@@ -27,6 +27,7 @@ use sha2::{Digest, Sha256};
2727use thiserror:: Error ;
2828use tokio:: { io:: AsyncRead , sync:: Semaphore } ;
2929use twirp:: client:: Client as TwirpClient ;
30+ use twirp:: { ClientError , TwirpErrorCode , TwirpErrorResponse } ;
3031use unicode_bom:: Bom ;
3132use url:: Url ;
3233
@@ -549,7 +550,11 @@ impl Api {
549550 . send ( )
550551 . await ?
551552 . check ( )
552- . await ?;
553+ . await
554+ . inspect_err ( |e| {
555+ self . circuit_breaker_429_tripped
556+ . check_err ( & e, & self . circuit_breaker_429_tripped_callback ) ;
557+ } ) ?;
553558
554559 offset += chunk_len;
555560 }
@@ -565,7 +570,11 @@ impl Api {
565570 . send ( )
566571 . await ?
567572 . check ( )
568- . await ?;
573+ . await
574+ . inspect_err ( |e| {
575+ self . circuit_breaker_429_tripped
576+ . check_err ( & e, & self . circuit_breaker_429_tripped_callback ) ;
577+ } ) ?;
569578
570579 let request = FinalizeCacheEntryUploadRequest {
571580 metadata : None ,
@@ -574,18 +583,21 @@ impl Api {
574583 version : self . version . clone ( ) ,
575584 } ;
576585
577- let response = self . twirp_client . finalize_cache_entry_upload ( request) . await ;
578-
579- match response {
580- Ok ( response) => {
586+ self . twirp_client
587+ . finalize_cache_entry_upload ( request)
588+ . await
589+ . map_err ( |e| e. into ( ) )
590+ . and_then ( |response| {
581591 if response. ok {
582592 Ok ( offset)
583593 } else {
584594 Err ( Error :: ApiErrorNotOk )
585595 }
586- }
587- Err ( e) => Err ( e. into ( ) ) ,
588- }
596+ } )
597+ . inspect_err ( |e| {
598+ self . circuit_breaker_429_tripped
599+ . check_err ( & e, & self . circuit_breaker_429_tripped_callback ) ;
600+ } )
589601 }
590602 }
591603 }
@@ -639,26 +651,26 @@ impl Api {
639651 Err ( e) => Err ( e) ,
640652 }
641653 } else {
642- let res = self
643- . twirp_client
654+ self . twirp_client
644655 . get_cache_entry_download_url ( GetCacheEntryDownloadUrlRequest {
645656 version : self . version . clone ( ) ,
646657 key : keys[ 0 ] . to_string ( ) ,
647658 restore_keys : keys. iter ( ) . map ( |k| k. to_string ( ) ) . collect ( ) ,
648659 metadata : None ,
649660 } )
650- . await ;
651-
652- match res {
653- Ok ( entry) => {
661+ . await
662+ . map_err ( |e| e. into ( ) )
663+ . and_then ( |entry| {
654664 if entry. ok {
655665 Ok ( Some ( entry. signed_download_url ) )
656666 } else {
657667 Ok ( None )
658668 }
659- }
660- Err ( e) => Err ( e. into ( ) ) ,
661- }
669+ } )
670+ . inspect_err ( |e| {
671+ self . circuit_breaker_429_tripped
672+ . check_err ( & e, & self . circuit_breaker_429_tripped_callback ) ;
673+ } )
662674 }
663675 }
664676
@@ -702,7 +714,22 @@ impl Api {
702714 version : self . version . clone ( ) ,
703715 } ;
704716
705- let res = self . twirp_client . create_cache_entry ( req) . await ?;
717+ let res = self
718+ . twirp_client
719+ . create_cache_entry ( req)
720+ . await
721+ . map_err ( |e| e. into ( ) )
722+ . and_then ( |response| {
723+ if response. ok {
724+ Ok ( response)
725+ } else {
726+ Err ( Error :: ApiErrorNotOk )
727+ }
728+ } )
729+ . inspect_err ( |e| {
730+ self . circuit_breaker_429_tripped
731+ . check_err ( & e, & self . circuit_breaker_429_tripped_callback ) ;
732+ } ) ?;
706733
707734 Ok ( FileAllocation :: V2 ( SignedUrl {
708735 signed_url : res. signed_upload_url ,
@@ -799,14 +826,31 @@ impl AtomicCircuitBreaker for AtomicBool {
799826 }
800827
801828 fn check_err ( & self , e : & Error , callback : & CircuitBreakerTrippedCallback ) {
802- if let Error :: ApiError {
803- status : reqwest:: StatusCode :: TOO_MANY_REQUESTS ,
804- ..
805- } = e
806- {
807- tracing:: info!( "Disabling GitHub Actions Cache due to 429: Too Many Requests" ) ;
808- self . store ( true , Ordering :: Relaxed ) ;
809- callback ( ) ;
829+ match e {
830+ Error :: ApiError {
831+ status : reqwest:: StatusCode :: TOO_MANY_REQUESTS ,
832+ ..
833+ }
834+ | Error :: TwirpError ( ClientError :: TwirpError ( TwirpErrorResponse {
835+ code : TwirpErrorCode :: ResourceExhausted ,
836+ ..
837+ } ) )
838+ | Error :: TwirpError ( ClientError :: HttpError {
839+ // The cache backend seems to give out this error for overload:
840+ // Twirp error: http error, status code: 502 Bad Gateway, msg:unknown error
841+ status : StatusCode :: BAD_GATEWAY ,
842+ ..
843+ } ) => {
844+ // meat is below
845+ }
846+ otherwise => {
847+ tracing:: error!( %otherwise, "Checked error for resource exhaustion, but it appears to be a different cause" ) ;
848+ return ;
849+ }
810850 }
851+
852+ tracing:: info!( %e, "Disabling GitHub Actions Cache due to rate limiting" ) ;
853+ self . store ( true , Ordering :: Relaxed ) ;
854+ callback ( ) ;
811855 }
812856}
0 commit comments