hive-c0re: bound forge API calls so a stalled forge can't wedge the swarm event loop
forgejo-api 0.11.1 takes no caller-built client, so a request to a forge that accepts the connection and never answers waited forever. Every forge::api() call site now goes through forge::bounded, a 10s timeout that errors naming the operation. The PR-comment calls run inline in swarm_status::drain_swarm_events, the one task serving both swarm subscriptions, so a stalled forge stopped both. Refs #5066
This commit is contained in:
parent
7214b4c22f
commit
2b0154be28
5 changed files with 111 additions and 41 deletions
|
|
@ -16,8 +16,8 @@ use reqwest::StatusCode;
|
|||
use crate::coordinator::Coordinator;
|
||||
|
||||
use super::{
|
||||
CONFIG_ORG, api, core_auth_header, core_token, forge_git_url, forge_http_base, is_present,
|
||||
reader_token,
|
||||
CONFIG_ORG, api, bounded, core_auth_header, core_token, forge_git_url, forge_http_base,
|
||||
is_present, reader_token,
|
||||
};
|
||||
|
||||
/// Creation options for an empty repo defaulting to `main`.
|
||||
|
|
@ -79,10 +79,13 @@ fn created_or_exists(res: Result<Repository, ForgejoError>, label: &str) -> Resu
|
|||
/// to the user we want the repo owned by (we use `core`'s token for
|
||||
/// `core/meta`). Idempotent.
|
||||
pub async fn ensure_repo(name: &str, token: &str) -> Result<()> {
|
||||
let res = api(token)?
|
||||
.create_current_user_repo(repo_option(name, true))
|
||||
.await;
|
||||
created_or_exists(res, &format!("core/{name}"))
|
||||
let label = format!("core/{name}");
|
||||
let res = bounded(
|
||||
&format!("create repo {label}"),
|
||||
api(token)?.create_current_user_repo(repo_option(name, true)),
|
||||
)
|
||||
.await?;
|
||||
created_or_exists(res, &label)
|
||||
}
|
||||
|
||||
/// Dashboard-warning guard for the meta non-fast-forward condition.
|
||||
|
|
@ -397,21 +400,24 @@ async fn add_collaborator(
|
|||
permission: AddCollaboratorOptionPermission,
|
||||
token: &str,
|
||||
) -> Result<()> {
|
||||
let res = api(token)?
|
||||
.repo_add_collaborator(
|
||||
let op = format!("add collaborator {user} to {owner}/{repo}");
|
||||
let res = bounded(
|
||||
&op,
|
||||
api(token)?.repo_add_collaborator(
|
||||
owner,
|
||||
repo,
|
||||
user,
|
||||
AddCollaboratorOption {
|
||||
permission: Some(permission),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
match res {
|
||||
Ok(()) => {}
|
||||
Err(ForgejoError::UnexpectedStatusCode(s)) if s == StatusCode::CREATED => {}
|
||||
Err(e) => {
|
||||
return Err(e).with_context(|| format!("add collaborator {user} to {owner}/{repo}"));
|
||||
return Err(e).context(op);
|
||||
}
|
||||
}
|
||||
tracing::debug!(%owner, %repo, %user, ?permission, "forge: collaborator set");
|
||||
|
|
|
|||
Loading…
Reference in a new issue