bound swarm webhook registration with the forge deadline
This commit is contained in:
parent
e405c2b098
commit
592ac8a5f2
1 changed files with 38 additions and 1 deletions
|
|
@ -1563,8 +1563,23 @@ impl Client {
|
||||||
///
|
///
|
||||||
/// Returns the first failure. A listing failure is not fatal — it falls
|
/// Returns the first failure. A listing failure is not fatal — it falls
|
||||||
/// through to the create attempt, which is idempotent server-side by way
|
/// through to the create attempt, which is idempotent server-side by way
|
||||||
/// of the already-exists fold.
|
/// of the already-exists fold. A forge that does not answer within
|
||||||
|
/// [`FORGE_DEADLINE`] is a failure too.
|
||||||
pub async fn ensure_swarm_webhooks(&self, public_base: &str, secret: &str) -> Result<()> {
|
pub async fn ensure_swarm_webhooks(&self, public_base: &str, secret: &str) -> Result<()> {
|
||||||
|
within_forge_deadline(
|
||||||
|
"register swarm webhooks",
|
||||||
|
self.ensure_all_swarm_hooks(public_base, secret),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
anyhow::bail!(
|
||||||
|
"the forge did not answer within {}s",
|
||||||
|
FORGE_DEADLINE.as_secs()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn ensure_all_swarm_hooks(&self, public_base: &str, secret: &str) -> Result<()> {
|
||||||
for kind in DeliveryKind::ALL {
|
for kind in DeliveryKind::ALL {
|
||||||
let target_url = kind.target_url(public_base);
|
let target_url = kind.target_url(public_base);
|
||||||
let (event, scope) = match kind {
|
let (event, scope) = match kind {
|
||||||
|
|
@ -2078,6 +2093,28 @@ mod tests {
|
||||||
assert_eq!(within_forge_deadline("test", async { 7 }).await, Some(7));
|
assert_eq!(within_forge_deadline("test", async { 7 }).await, Some(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A forge that accepts the connection and never answers fails the
|
||||||
|
/// registration at the deadline, so the caller's retry advances. The
|
||||||
|
/// paused clock jumps to the deadline once nothing else can run.
|
||||||
|
#[tokio::test(start_paused = true)]
|
||||||
|
async fn swarm_webhook_registration_fails_at_the_deadline_when_the_forge_never_answers() {
|
||||||
|
// Bound but never accepted: the handshake completes, no response comes.
|
||||||
|
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||||
|
let url = url::Url::parse(&format!("http://{}/", listener.local_addr().unwrap())).unwrap();
|
||||||
|
let client = Client::for_test_forge(url);
|
||||||
|
let start = tokio::time::Instant::now();
|
||||||
|
// The outer bound turns a missing deadline into a failure, not a hang.
|
||||||
|
let err = tokio::time::timeout(
|
||||||
|
FORGE_DEADLINE * 2,
|
||||||
|
client.ensure_swarm_webhooks("https://swarm.example", "s3cret"),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("registration returns by itself")
|
||||||
|
.expect_err("no answer is a failure");
|
||||||
|
assert_eq!(start.elapsed(), FORGE_DEADLINE);
|
||||||
|
assert!(format!("{err:#}").contains("did not answer"), "{err:#}");
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn page_search_results_pages_past_a_full_first_page() {
|
async fn page_search_results_pages_past_a_full_first_page() {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue