Watch
0
0
Fork
You've already forked hyperhive
0

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:
atlas 2026-10-09 15:30:57 +02:00 • committed by mara
commit 2b0154be28
5 changed files with 111 additions and 41 deletions

View file

@ -4,7 +4,7 @@
use anyhow::{Context, Result};
use super::{CONFIG_ORG, api, core_token, reader_token};
use super::{CONFIG_ORG, api, bounded, core_token, reader_token};
/// Full `owner/name` path of an agent's config repo on the forge.
pub fn config_repo(agent: &str) -> String {
@ -20,10 +20,12 @@ pub async fn merged_pr_for_commit(repo: &str, sha: &str) -> Result<u64> {
let (owner, name) = repo
.split_once('/')
.with_context(|| format!("forge repo `{repo}` is not owner/name"))?;
let pull = api(reader.value())?
.repo_get_commit_pull_request(owner, name, sha)
.await
.context("GET pull request of commit")?;
let pull = bounded(
"GET pull request of commit",
api(reader.value())?.repo_get_commit_pull_request(owner, name, sha),
)
.await?
.context("GET pull request of commit")?;
pull.number
.and_then(|n| u64::try_from(n).ok())
.with_context(|| format!("pull request of {sha} in {repo} carries no number"))
@ -40,8 +42,9 @@ pub async fn post_pr_comment(repo: &str, pr: u64, body: &str) -> Result<()> {
.split_once('/')
.with_context(|| format!("forge repo `{repo}` is not owner/name"))?;
let index = i64::try_from(pr).with_context(|| format!("PR index {pr} overflows i64"))?;
api(&token)?
.issue_create_comment(
bounded(
"post PR comment",
api(&token)?.issue_create_comment(
owner,
name,
index,
@ -49,8 +52,9 @@ pub async fn post_pr_comment(repo: &str, pr: u64, body: &str) -> Result<()> {
body: body.to_owned(),
updated_at: None,
},
)
.await
.context("post PR comment")?;
),
)
.await?
.context("post PR comment")?;
Ok(())
}