Skip to content

Commit f051133

Browse files
committed
fix(desktop): wait for occupied backend readiness
1 parent 4fea3e1 commit f051133

2 files changed

Lines changed: 24 additions & 8 deletions

File tree

‎src-tauri/src/lib.rs‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,12 @@ fn health_check_ready() -> bool {
213213
Ok(value) => value,
214214
Err(_) => return false,
215215
};
216-
let mut stream = match TcpStream::connect_timeout(&addr, Duration::from_millis(300)) {
216+
let mut stream = match TcpStream::connect_timeout(&addr, Duration::from_millis(1000)) {
217217
Ok(value) => value,
218218
Err(_) => return false,
219219
};
220-
let _ = stream.set_read_timeout(Some(Duration::from_millis(500)));
221-
let _ = stream.set_write_timeout(Some(Duration::from_millis(500)));
220+
let _ = stream.set_read_timeout(Some(Duration::from_millis(1500)));
221+
let _ = stream.set_write_timeout(Some(Duration::from_millis(1000)));
222222

223223
let body = r#"{"action":"health-check","params":{}}"#;
224224
let request = format!(
@@ -244,7 +244,7 @@ fn backend_port_occupied() -> bool {
244244
Ok(value) => value,
245245
Err(_) => return false,
246246
};
247-
TcpStream::connect_timeout(&addr, Duration::from_millis(300)).is_ok()
247+
TcpStream::connect_timeout(&addr, Duration::from_millis(1000)).is_ok()
248248
}
249249

250250
fn backend_port_occupied_message() -> String {
@@ -535,6 +535,14 @@ fn spawn_backend(app: &tauri::App) -> Result<Option<Child>, Box<dyn std::error::
535535
return Ok(None);
536536
}
537537

538+
if backend_port_occupied() {
539+
desktop_log("backend port is occupied but not ready yet; waiting before stale cleanup");
540+
if wait_for_backend(Duration::from_secs(5)) {
541+
desktop_log("existing backend became ready while waiting; reusing 127.0.0.1:3737 listener");
542+
return Ok(None);
543+
}
544+
}
545+
538546
release_stale_backend_port();
539547

540548
if health_check_ready() {
@@ -543,8 +551,13 @@ fn spawn_backend(app: &tauri::App) -> Result<Option<Child>, Box<dyn std::error::
543551
}
544552

545553
if backend_port_occupied() {
554+
desktop_log("backend port remains occupied after cleanup; waiting once more before surfacing occupied-port error");
555+
if wait_for_backend(Duration::from_secs(5)) {
556+
desktop_log("backend became ready after occupied-port grace wait; reusing 127.0.0.1:3737 listener");
557+
return Ok(None);
558+
}
546559
let message = backend_port_occupied_message();
547-
desktop_log(format!("backend port remains occupied after cleanup; {message}"));
560+
desktop_log(format!("backend port remains occupied after cleanup and grace wait; {message}"));
548561
return startup_error(message);
549562
}
550563

‎tests/unit/desktop-diagnostics-contract.test.mjs‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,11 @@ test('desktop startup reuses healthy backend before clearing stale port listener
6565

6666
assert.match(libSource, /fn release_stale_backend_port\(\) -> usize/);
6767
assert.match(libSource, /if health_check_ready\(\)[\s\S]*existing backend already ready[\s\S]*return Ok\(None\)/);
68+
assert.match(libSource, /backend port is occupied but not ready yet; waiting before stale cleanup/);
69+
assert.match(libSource, /if backend_port_occupied\(\)[\s\S]*wait_for_backend\(Duration::from_secs\(5\)\)[\s\S]*existing backend became ready while waiting[\s\S]*return Ok\(None\)/);
6870
assert.match(libSource, /release_stale_backend_port\(\);[\s\S]*if health_check_ready\(\)[\s\S]*backend became ready after stale port cleanup[\s\S]*return Ok\(None\)/);
69-
assert.match(libSource, /release_stale_backend_port\(\);[\s\S]*if backend_port_occupied\(\)/);
71+
assert.match(libSource, /backend port remains occupied after cleanup; waiting once more before surfacing occupied-port error/);
72+
assert.match(libSource, /backend became ready after occupied-port grace wait[\s\S]*return Ok\(None\)/);
7073
assert.match(libSource, /local_address\.starts_with\("127\.0\.0\.1:"\)/);
7174
assert.match(libSource, /local_address\.starts_with\("\[::1\]:"\)/);
7275
assert.match(libSource, /non-local listener/);
@@ -119,8 +122,8 @@ test('desktop startup surfaces occupied backend port guidance instead of waiting
119122
assert.match(libSource, /端口 3737 已被其他进程占用/);
120123
assert.match(libSource, /Windows 桌面版启动时会请求管理员权限/);
121124
assert.match(libSource, /详情见 startup\.log/);
122-
assert.match(libSource, /if backend_port_occupied\(\)[\s\S]*return startup_error\(message\)/);
123-
assert.match(libSource, /backend port remains occupied after cleanup/);
125+
assert.match(libSource, /if backend_port_occupied\(\)[\s\S]*wait_for_backend\(Duration::from_secs\(5\)\)[\s\S]*return startup_error\(message\)/);
126+
assert.match(libSource, /backend port remains occupied after cleanup and grace wait/);
124127
});
125128

126129
test('desktop windows installer supports overwrite-style reinstall flow', () => {

0 commit comments

Comments
 (0)