huskies: merge 655_bug_matrix_bot_spawns_its_own_timerstore_instead_of_using_shared_appcontext_timer_store

This commit is contained in:
dave
2026-04-27 11:28:21 +00:00
parent ac85cfce5d
commit 65d2fb210c
4 changed files with 14 additions and 10 deletions
+2 -3
View File
@@ -1,4 +1,5 @@
//! Matrix bot run loop — connects to the homeserver and processes sync events. //! Matrix bot run loop — connects to the homeserver and processes sync events.
use crate::service::timer::TimerStore;
use crate::services::Services; use crate::services::Services;
use crate::slog; use crate::slog;
use matrix_sdk::ruma::OwnedRoomId; use matrix_sdk::ruma::OwnedRoomId;
@@ -28,6 +29,7 @@ pub async fn run_bot(
gateway_active_project: Option<Arc<RwLock<String>>>, gateway_active_project: Option<Arc<RwLock<String>>>,
gateway_projects: Vec<String>, gateway_projects: Vec<String>,
gateway_project_urls: std::collections::BTreeMap<String, String>, gateway_project_urls: std::collections::BTreeMap<String, String>,
timer_store: Arc<TimerStore>,
) -> Result<(), String> { ) -> Result<(), String> {
let project_root = &services.project_root; let project_root = &services.project_root;
let store_path = project_root.join(".huskies").join("matrix_store"); let store_path = project_root.join(".huskies").join("matrix_store");
@@ -224,9 +226,6 @@ pub async fn run_bot(
let announce_bot_name = services.bot_name.clone(); let announce_bot_name = services.bot_name.clone();
let timer_store = Arc::new(crate::service::timer::TimerStore::load(
project_root.join(".huskies").join("timers.json"),
));
// Auto-schedule timers when an agent hits a hard rate limit. // Auto-schedule timers when an agent hits a hard rate limit.
crate::service::timer::spawn_rate_limit_auto_scheduler( crate::service::timer::spawn_rate_limit_auto_scheduler(
Arc::clone(&timer_store), Arc::clone(&timer_store),
+3
View File
@@ -32,6 +32,7 @@ pub use config::BotConfig;
use crate::io::watcher::WatcherEvent; use crate::io::watcher::WatcherEvent;
use crate::rebuild::ShutdownReason; use crate::rebuild::ShutdownReason;
use crate::service::timer::TimerStore;
use crate::services::Services; use crate::services::Services;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
@@ -69,6 +70,7 @@ pub fn spawn_bot(
gateway_active_project: Option<Arc<RwLock<String>>>, gateway_active_project: Option<Arc<RwLock<String>>>,
gateway_projects: Vec<String>, gateway_projects: Vec<String>,
gateway_project_urls: std::collections::BTreeMap<String, String>, gateway_project_urls: std::collections::BTreeMap<String, String>,
timer_store: Arc<TimerStore>,
) -> Option<tokio::task::AbortHandle> { ) -> Option<tokio::task::AbortHandle> {
let config = match BotConfig::load(project_root) { let config = match BotConfig::load(project_root) {
Some(c) => c, Some(c) => c,
@@ -105,6 +107,7 @@ pub fn spawn_bot(
gateway_active_project, gateway_active_project,
gateway_projects, gateway_projects,
gateway_project_urls, gateway_project_urls,
timer_store,
) )
.await .await
{ {
+5 -7
View File
@@ -629,14 +629,10 @@ async fn main() -> Result<(), std::io::Error> {
let matrix_shutdown_tx = Arc::new(matrix_shutdown_tx); let matrix_shutdown_tx = Arc::new(matrix_shutdown_tx);
let matrix_shutdown_tx_for_rebuild = Arc::clone(&matrix_shutdown_tx); let matrix_shutdown_tx_for_rebuild = Arc::clone(&matrix_shutdown_tx);
// Bug 501: shared rate-limit retry timer store, accessible from MCP tools // Shared rate-limit retry timer store, accessible from MCP tools via
// via AppContext so manual interventions (move_story → backlog, stop_agent) // AppContext so manual interventions (move_story → backlog, stop_agent)
// can cancel pending timers in-memory rather than only on disk. // can cancel pending timers in-memory rather than only on disk.
// // Also shared with the Matrix bot tick loop (bug 655).
// TODO(bug 501): the matrix bot currently spawns its own TimerStore instance
// in `chat::transport::matrix::bot::run::spawn_bot`. Refactor to consume this
// shared instance via `AppContext.timer_store` so cancellations from MCP
// tools and the bot's tick loop see the same in-memory state.
let timer_store = std::sync::Arc::new(crate::service::timer::TimerStore::load( let timer_store = std::sync::Arc::new(crate::service::timer::TimerStore::load(
startup_root startup_root
.as_ref() .as_ref()
@@ -645,6 +641,7 @@ async fn main() -> Result<(), std::io::Error> {
)); ));
let timer_store_for_tick = Arc::clone(&timer_store); let timer_store_for_tick = Arc::clone(&timer_store);
let timer_store_for_bot = Arc::clone(&timer_store);
let ctx = AppContext { let ctx = AppContext {
state: app_state, state: app_state,
@@ -738,6 +735,7 @@ async fn main() -> Result<(), std::io::Error> {
None, None,
vec![], vec![],
std::collections::BTreeMap::new(), std::collections::BTreeMap::new(),
timer_store_for_bot,
); );
} else { } else {
// Keep the receiver alive (drop it) so the sender never errors. // Keep the receiver alive (drop it) so the sender never errors.
+4
View File
@@ -409,6 +409,9 @@ pub fn spawn_gateway_bot(
status: std::sync::Arc::new(crate::service::status::StatusBroadcaster::new()), status: std::sync::Arc::new(crate::service::status::StatusBroadcaster::new()),
}); });
let timer_store = std::sync::Arc::new(crate::service::timer::TimerStore::load(
config_dir.join(".huskies").join("timers.json"),
));
crate::chat::transport::matrix::spawn_bot( crate::chat::transport::matrix::spawn_bot(
config_dir, config_dir,
watcher_tx, watcher_tx,
@@ -417,5 +420,6 @@ pub fn spawn_gateway_bot(
Some(active_project), Some(active_project),
gateway_projects, gateway_projects,
gateway_project_urls, gateway_project_urls,
timer_store,
) )
} }