fix(state): jangan bangun mention index di mode attach
AppStateRest::new() men-spawn thread ignore::Walk untuk mention_index tanpa syarat, padahal mode --attach cuma dipakai untuk render lokal — handle_key dan logika mention berjalan di sisi daemon lewat IPC, jadi index di client attach tidak pernah dipakai. Ini bikin setiap --attach melakukan full workspace walk (sampai 50.000 entry) sia-sia. Pindahkan thread-spawn itu ke method terpisah spawn_mention_index_build(), dipanggil eksplisit dari run_single_process() dan run_daemon() setelah AppStateRest::new(), tapi sengaja tidak dipanggil dari run_attach().
This commit is contained in:
+29
-20
@@ -206,23 +206,35 @@ impl AppStateRest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire-and-forget background file index build for `@file` mention
|
state
|
||||||
// autocomplete.
|
}
|
||||||
//
|
|
||||||
// Flow: spawn OS thread -> `ignore::Walk` each workspace root,
|
/// Spawn the background thread that walks every workspace root and
|
||||||
// collecting file paths (workspace-index-prefixed for roots beyond
|
/// populates `mention_index` for `@file` mention autocomplete.
|
||||||
// the first, matching `resolve_path`'s `[N]path` convention) -> stop
|
///
|
||||||
// once 50,000 entries are collected -> store the result in
|
/// Why a separate method, not called from `new()`: the attach-only
|
||||||
// `mention_index`.
|
/// TUI client also constructs an `AppStateRest` (for local rendering
|
||||||
//
|
/// state) but never runs tools or `handle_key` locally — it forwards
|
||||||
// Why a raw thread and not a background tokio task: there is no
|
/// keystrokes to the daemon over IPC, which has its own `AppStateRest`
|
||||||
// persistent async runtime driving the render loop, and this is
|
/// with its own index. Spawning this walk in the attach client would
|
||||||
// blocking filesystem I/O -- a dedicated thread keeps startup
|
/// waste a full workspace scan for an index nothing there consumes.
|
||||||
// non-blocking. Not joined, same rationale as the LSP provisioning
|
/// Callers that DO need the index (single-process mode, the daemon)
|
||||||
// thread above: a slow/huge repo must not delay the TUI appearing.
|
/// call this explicitly after construction.
|
||||||
{
|
///
|
||||||
let mention_index = state.mention_index.clone();
|
/// Flow: spawn OS thread -> `ignore::Walk` each workspace root,
|
||||||
let roots = state.workspace_roots.clone();
|
/// collecting file paths (workspace-index-prefixed for roots beyond
|
||||||
|
/// the first, matching `resolve_path`'s `[N]path` convention) -> stop
|
||||||
|
/// once 50,000 entries are collected -> store the result in
|
||||||
|
/// `mention_index`.
|
||||||
|
///
|
||||||
|
/// Why a raw thread and not a background tokio task: there is no
|
||||||
|
/// persistent async runtime driving the render loop, and this is
|
||||||
|
/// blocking filesystem I/O -- a dedicated thread keeps startup
|
||||||
|
/// non-blocking. Not joined, same rationale as the LSP provisioning
|
||||||
|
/// thread above: a slow/huge repo must not delay the TUI appearing.
|
||||||
|
pub fn spawn_mention_index_build(&self) {
|
||||||
|
let mention_index = self.mention_index.clone();
|
||||||
|
let roots = self.workspace_roots.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
const MAX_MENTION_ENTRIES: usize = 50_000;
|
const MAX_MENTION_ENTRIES: usize = 50_000;
|
||||||
let mut paths = Vec::new();
|
let mut paths = Vec::new();
|
||||||
@@ -244,9 +256,6 @@ impl AppStateRest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
state
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether an agent turn is currently running.
|
/// Whether an agent turn is currently running.
|
||||||
///
|
///
|
||||||
/// Return: `false` (and logs a warning) if the mutex is poisoned, rather
|
/// Return: `false` (and logs a warning) if the mutex is poisoned, rather
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ fn run_single_process() -> Result<()> {
|
|||||||
&session_dir,
|
&session_dir,
|
||||||
store.memory_dir,
|
store.memory_dir,
|
||||||
);
|
);
|
||||||
|
state.spawn_mention_index_build();
|
||||||
state.sessions = model::session::Session::list(&store.base_dir);
|
state.sessions = model::session::Session::list(&store.base_dir);
|
||||||
|
|
||||||
|
|
||||||
@@ -442,6 +443,7 @@ fn run_daemon() -> Result<()> {
|
|||||||
&session_dir,
|
&session_dir,
|
||||||
store.memory_dir,
|
store.memory_dir,
|
||||||
);
|
);
|
||||||
|
state.spawn_mention_index_build();
|
||||||
state.sessions = model::session::Session::list(&store.base_dir);
|
state.sessions = model::session::Session::list(&store.base_dir);
|
||||||
|
|
||||||
let _rt = tokio::runtime::Runtime::new()?;
|
let _rt = tokio::runtime::Runtime::new()?;
|
||||||
|
|||||||
Reference in New Issue
Block a user