huskies: merge 898
This commit is contained in:
@@ -21,13 +21,23 @@ pub fn load_config(path: &Path) -> Result<GatewayConfig, String> {
|
||||
|
||||
/// Persist the current projects map to `<config_dir>/projects.toml`.
|
||||
/// Silently ignores write errors or skips when `config_dir` is empty.
|
||||
///
|
||||
/// Existing `[sled_tokens]` entries are preserved so that adding or removing
|
||||
/// projects via the UI does not wipe the sled authentication tokens.
|
||||
pub async fn save_config(projects: &BTreeMap<String, ProjectEntry>, config_dir: &Path) {
|
||||
if config_dir.as_os_str().is_empty() {
|
||||
return;
|
||||
}
|
||||
let path = config_dir.join("projects.toml");
|
||||
let sled_tokens = tokio::fs::read_to_string(&path)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|data| toml::from_str::<GatewayConfig>(&data).ok())
|
||||
.map(|c| c.sled_tokens)
|
||||
.unwrap_or_default();
|
||||
let config = GatewayConfig {
|
||||
projects: projects.clone(),
|
||||
sled_tokens,
|
||||
};
|
||||
if let Ok(data) = toml::to_string_pretty(&config) {
|
||||
let _ = tokio::fs::write(&path, data).await;
|
||||
@@ -518,27 +528,20 @@ pub fn spawn_gateway_bot(
|
||||
gateway_project_urls: BTreeMap<String, String>,
|
||||
port: u16,
|
||||
gateway_event_tx: Option<tokio::sync::broadcast::Sender<super::GatewayStatusEvent>>,
|
||||
perm_rx: std::sync::Arc<
|
||||
tokio::sync::Mutex<
|
||||
tokio::sync::mpsc::UnboundedReceiver<crate::http::context::PermissionForward>,
|
||||
>,
|
||||
>,
|
||||
) -> (
|
||||
Option<tokio::task::AbortHandle>,
|
||||
tokio::sync::watch::Sender<Option<crate::rebuild::ShutdownReason>>,
|
||||
) {
|
||||
use crate::agents::AgentPool;
|
||||
use crate::services::Services;
|
||||
use tokio::sync::{broadcast, mpsc};
|
||||
|
||||
let (watcher_tx, _) = broadcast::channel(16);
|
||||
let (perm_tx, perm_rx) = mpsc::unbounded_channel();
|
||||
// Keep the sender alive for the gateway's lifetime so the matrix bot's
|
||||
// `permission_listener` task doesn't exit immediately with
|
||||
// "perm_rx channel closed". Previously `_perm_tx` was dropped when
|
||||
// `spawn_gateway_bot` returned, closing the channel before the
|
||||
// listener could even register. Story 898 (sled→gateway WS uplink)
|
||||
// will eventually wire in a real sender; for now the leak keeps the
|
||||
// channel open with no senders writing to it, matching the original
|
||||
// intent of "listener watches forever, waiting for requests".
|
||||
std::mem::forget(perm_tx);
|
||||
let perm_rx = std::sync::Arc::new(tokio::sync::Mutex::new(perm_rx));
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
let (watcher_tx, _) = broadcast::channel::<crate::io::watcher::WatcherEvent>(16);
|
||||
let (shutdown_tx, shutdown_rx) =
|
||||
tokio::sync::watch::channel::<Option<crate::rebuild::ShutdownReason>>(None);
|
||||
// shutdown_tx is intentionally NOT forgotten — the caller holds it and
|
||||
@@ -611,6 +614,9 @@ mod tests {
|
||||
let active = std::sync::Arc::new(tokio::sync::RwLock::new("proj".to_string()));
|
||||
let (event_tx, _) = tokio::sync::broadcast::channel(4);
|
||||
|
||||
let (_perm_tx, perm_rx) =
|
||||
tokio::sync::mpsc::unbounded_channel::<crate::http::context::PermissionForward>();
|
||||
let perm_rx = std::sync::Arc::new(tokio::sync::Mutex::new(perm_rx));
|
||||
let (handle, shutdown_tx) = spawn_gateway_bot(
|
||||
tmp.path(),
|
||||
active,
|
||||
@@ -618,6 +624,7 @@ mod tests {
|
||||
std::collections::BTreeMap::new(),
|
||||
3001,
|
||||
Some(event_tx),
|
||||
perm_rx,
|
||||
);
|
||||
|
||||
// No bot.toml in tmp → no abort handle spawned.
|
||||
|
||||
Reference in New Issue
Block a user