Skip to content

Commit 93bcd50

Browse files
authored
Merge pull request #145 from DeterminateSystems/push-lnxvzuypxqsp
Trip the circuit breaker in the v2 paths too
2 parents 1152ede + ad47f5f commit 93bcd50

File tree

1 file changed

+71
-27
lines changed

1 file changed

+71
-27
lines changed

gha-cache/src/api.rs

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use sha2::{Digest, Sha256};
2727
use thiserror::Error;
2828
use tokio::{io::AsyncRead, sync::Semaphore};
2929
use twirp::client::Client as TwirpClient;
30+
use twirp::{ClientError, TwirpErrorCode, TwirpErrorResponse};
3031
use unicode_bom::Bom;
3132
use 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

Comments
 (0)