swarm-controller gains forge access when the token arrives, without a restart
A controller that started before the forge's host had published its token ran without forge access until someone restarted it: on a split-host first deploy that is a manual step. Now the forge client lives in a slot that is filled once (`Late<T>`, an `Arc<OnceLock<T>>`): - `forge::enable` tries the store once at start. On failure it logs once and re-reads in the background with backoff (30s doubling to a 5-minute cap, no log per retry), fills the slot and logs once when the token is there. - The forge passes (#5014's per-hive token mint among them), the config-PR poll and the webhook registration start from that moment, through `start_forge`'s callback. - Job nodes and HTTP handlers read the slot when they run, so they answer "no forge" before and work after. A token replaced in the store after the slot is filled still reaches the controller with its next restart. The round-1 change that shared `queue_identity::fetch_with_retry` is reverted; nothing else uses it. Refs #4998
This commit is contained in:
parent
121c4678aa
commit
c45f7a5330
11 changed files with 243 additions and 135 deletions
|
|
@ -33,7 +33,7 @@ use crate::forge;
|
|||
pub async fn get_repos(
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Json<Vec<String>>, StatusUnavailable> {
|
||||
let Some(client) = state.forge.as_ref() else {
|
||||
let Some(client) = state.forge.get() else {
|
||||
return Err(StatusUnavailable(
|
||||
"no forge is configured on this host".to_owned(),
|
||||
));
|
||||
|
|
@ -64,7 +64,7 @@ pub async fn get_repos(
|
|||
pub async fn get_issue_report_all(
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Json<Vec<forge::IssueReportRow>>, StatusUnavailable> {
|
||||
let Some(client) = state.forge.as_ref() else {
|
||||
let Some(client) = state.forge.get() else {
|
||||
return Err(StatusUnavailable(
|
||||
"no forge is configured on this host".to_owned(),
|
||||
));
|
||||
|
|
@ -109,7 +109,7 @@ pub async fn get_issue_report(
|
|||
State(state): State<AppState>,
|
||||
Path((org, repo)): Path<(String, String)>,
|
||||
) -> Result<Json<Vec<forge::IssueReportRow>>, problem_details::ProblemDetails> {
|
||||
let Some(client) = state.forge.as_ref() else {
|
||||
let Some(client) = state.forge.get() else {
|
||||
return Err(error_problem(
|
||||
axum::http::StatusCode::SERVICE_UNAVAILABLE,
|
||||
"no forge is configured on this host",
|
||||
|
|
|
|||
Loading…
Reference in a new issue