various: reuse HTTP client; eliminate intermediate string allocations; add tests

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I18b89e1aae78a400a89c9d89423ce1da6a6a6964
This commit is contained in:
raf 2026-02-15 23:30:45 +03:00
commit f7081317ee
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
9 changed files with 245 additions and 96 deletions

View file

@ -1,5 +1,7 @@
//! Notification dispatch for build events
use std::sync::OnceLock;
use tracing::{error, info, warn};
use crate::{
@ -7,6 +9,13 @@ use crate::{
models::{Build, BuildStatus, Project},
};
/// Shared HTTP client for all notification dispatches.
/// Avoids recreating connection pools on every build completion.
fn http_client() -> &'static reqwest::Client {
static CLIENT: OnceLock<reqwest::Client> = OnceLock::new();
CLIENT.get_or_init(reqwest::Client::new)
}
/// Dispatch all configured notifications for a completed build.
pub async fn dispatch_build_finished(
build: &Build,
@ -113,8 +122,7 @@ async fn set_github_status(
"context": format!("fc/{}", build.job_name),
});
let client = reqwest::Client::new();
match client
match http_client()
.post(&url)
.header("Authorization", format!("token {token}"))
.header("User-Agent", "fc-ci")
@ -166,8 +174,7 @@ async fn set_gitea_status(
"context": format!("fc/{}", build.job_name),
});
let client = reqwest::Client::new();
match client
match http_client()
.post(&url)
.header("Authorization", format!("token {token}"))
.json(&body)
@ -226,8 +233,7 @@ async fn set_gitlab_status(
"name": format!("fc/{}", build.job_name),
});
let client = reqwest::Client::new();
match client
match http_client()
.post(&url)
.header("PRIVATE-TOKEN", token)
.json(&body)