optimize: terminal spawn lifecycle to eliminate output race condition
Move PTY spawn from context layer to view layer so event subscription happens before spawn, preventing loss of initial terminal output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -69,11 +69,14 @@ pub(crate) fn prepare_credential_env(
|
||||
pub async fn terminal_spawn(
|
||||
working_dir: String,
|
||||
initial_command: Option<String>,
|
||||
terminal_id: Option<String>,
|
||||
manager: State<'_, TerminalManager>,
|
||||
app_handle: tauri::AppHandle,
|
||||
window: tauri::WebviewWindow,
|
||||
) -> Result<String, TerminalError> {
|
||||
let terminal_id = uuid::Uuid::new_v4().to_string();
|
||||
let terminal_id = terminal_id
|
||||
.filter(|id| !id.is_empty() && id.len() <= 256)
|
||||
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
|
||||
|
||||
let app_data_dir = app_handle
|
||||
.path()
|
||||
|
||||
@@ -162,6 +162,17 @@ impl TerminalManager {
|
||||
opts: SpawnOptions,
|
||||
emitter: EventEmitter,
|
||||
) -> Result<String, TerminalError> {
|
||||
// Reject duplicate IDs to prevent orphaning an existing PTY process.
|
||||
{
|
||||
let terminals = self.terminals.lock().unwrap();
|
||||
if terminals.contains_key(&opts.terminal_id) {
|
||||
return Err(TerminalError::SpawnFailed(format!(
|
||||
"terminal id '{}' already exists",
|
||||
opts.terminal_id
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
let pty_system = native_pty_system();
|
||||
|
||||
let pair = pty_system
|
||||
|
||||
@@ -18,6 +18,7 @@ use crate::terminal::types::TerminalInfo;
|
||||
pub struct TerminalSpawnParams {
|
||||
pub working_dir: String,
|
||||
pub initial_command: Option<String>,
|
||||
pub terminal_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -50,7 +51,10 @@ pub async fn terminal_spawn(
|
||||
Json(params): Json<TerminalSpawnParams>,
|
||||
) -> Result<Json<String>, AppCommandError> {
|
||||
let manager = &state.terminal_manager;
|
||||
let terminal_id = uuid::Uuid::new_v4().to_string();
|
||||
let terminal_id = params
|
||||
.terminal_id
|
||||
.filter(|id| !id.is_empty() && id.len() <= 256)
|
||||
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
|
||||
|
||||
let extra_env = prepare_credential_env(&state.data_dir);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user