Fix get_repo_info: Retry on rate limit

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2024-06-06 22:57:55 +10:00
parent d1aa7273c0
commit bc71a1b136
No known key found for this signature in database
GPG key ID: 76D1E687CA3C4928
2 changed files with 20 additions and 11 deletions

View file

@ -1,4 +1,4 @@
use std::{borrow::Cow, fmt, iter, path::Path, sync::Arc, time::Duration};
use std::{borrow::Cow, fmt, iter, path::Path, sync::Arc};
use binstalk_git_repo_api::gh_api_client::{GhApiError, GhReleaseArtifact, GhReleaseArtifactUrl};
use compact_str::{CompactString, ToCompactString};
@ -12,11 +12,9 @@ use url::Url;
use crate::{
common::*, futures_resolver::FuturesResolver, Data, FetchError, InvalidPkgFmtError, RepoInfo,
SignaturePolicy, SignatureVerifier, TargetDataErased,
SignaturePolicy, SignatureVerifier, TargetDataErased, DEFAULT_GH_API_RETRY_DURATION,
};
static DEFAULT_GH_API_RETRY_DURATION: Duration = Duration::from_secs(1);
pub(crate) mod hosting;
pub struct GhCrateMeta {

View file

@ -1,12 +1,12 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
use std::{path::Path, sync::Arc};
use std::{path::Path, sync::Arc, time::Duration};
use binstalk_downloader::{download::DownloadError, remote::Error as RemoteError};
use binstalk_git_repo_api::gh_api_client::{GhApiError, GhRepo};
use binstalk_types::cargo_toml_binstall::SigningAlgorithm;
use thiserror::Error as ThisError;
use tokio::sync::OnceCell;
use tokio::{sync::OnceCell, time::sleep};
pub use url::ParseError as UrlParseError;
mod gh_crate_meta;
@ -27,6 +27,8 @@ mod futures_resolver;
use gh_crate_meta::hosting::RepositoryHost;
static DEFAULT_GH_API_RETRY_DURATION: Duration = Duration::from_secs(1);
#[derive(Debug, ThisError)]
#[error("Invalid pkg-url {pkg_url} for {crate_name}@{version} on {target}: {reason}")]
pub struct InvalidPkgFmtError {
@ -204,11 +206,20 @@ impl Data {
let mut is_private = false;
if repository_host == RepositoryHost::GitHub && client.has_gh_token() {
if let Some(gh_repo) = GhRepo::try_extract_from_url(&repo) {
let Some(gh_repo_info) = client.get_repo_info(&gh_repo).await? else {
return Err(GhApiError::NotFound.into());
};
loop {
match client.get_repo_info(&gh_repo).await {
Ok(Some(gh_repo_info)) => {
is_private = gh_repo_info.is_private();
break;
}
Ok(None) => return Err(GhApiError::NotFound.into()),
Err(GhApiError::RateLimit { retry_after }) => {
sleep(retry_after.unwrap_or(DEFAULT_GH_API_RETRY_DURATION))
.await
}
Err(err) => return Err(err.into()),
}
}
}
}