connectors: announce global-server and reinstall refreshes on the bus
Nightly Build / build (push) Successful in 6m56s

Five call-sites reached into the live-runtime refresh helpers from HTTP
handlers, the same shape as the container remounts. Only three of them
belonged on the bus, and finding out which was the point.

global_enable and global_delete now emit McpGlobalServersChanged, and the
marketplace reinstall emits ConnectorReinstalled. All three are pure
reconciliation: the first only makes a connector appear; the second is
already enforced by stop_server, with the snapshot refresh just tidying
each user's filter; the third pushes metadata and code into what is
already running. The reinstall gains something from being off the
response path, since it re-copies files and restarts servers inside every
live user's container.

global_set_access and user_connectors_set keep calling
refresh_global_mcp_access directly. Their writes *replace* a grant set, so
anyone dropped from the list is being revoked and that refresh is what
enforces it — on a best-effort broadcast a revoked user would keep the
connector until their next login. Both carry a DELIBERATELY SYNCHRONOUS
comment, since they are otherwise indistinguishable from the announced
call-sites and are exactly what a later cleanup would sweep up.

No behaviour change for the two synchronous paths; the three announced
ones now return without waiting for the refresh.
This commit is contained in:
2026-07-26 22:22:29 +01:00
parent 0ba140186f
commit 305bdbdd2b
5 changed files with 59 additions and 18 deletions
+13 -7
View File
@@ -32,6 +32,7 @@ use axum::extract::{Extension, Path, Query, State};
use axum::http::header;
use axum::response::{IntoResponse, Response};
use axum::Json;
use core_api::system_bus::SystemEvent;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use sha2::{Digest, Sha256};
@@ -794,13 +795,18 @@ pub async fn install(
)
.await?;
// Push the (re)installed metadata + code into anything already running it, so a
// reinstall lands live instead of waiting for each user's next login: enabled
// global servers re-snapshot the description and restart; each live user who
// activated it gets its files/deps reconciled and the connector restarted with
// the fresh `llm_short_description`. A first-time install matches nothing live
// and is a cheap no-op.
skald.refresh_connector_after_reinstall(&body.id).await;
// Announce the (re)install so anything already running it catches up without
// waiting for each user's next login: enabled global servers re-snapshot the
// description and restart; each live user who activated it gets its files/deps
// reconciled and the connector restarted with the fresh `llm_short_description`.
// A first-time install matches nothing live and is a cheap no-op.
//
// On the bus, not awaited: the reaction re-copies files and restarts servers
// inside containers, which can take seconds per live user — the admin's install
// should not block on it, and nothing in the response below depends on it.
skald.system_bus().send(SystemEvent::ConnectorReinstalled {
catalog_name: body.id.clone(),
});
Ok(Json(json!({
"id": id,