mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
fix: prevent stale IM adapter sidecars
Telegram long polling can be consumed or disrupted by orphaned adapter sidecar processes left behind after desktop restarts or IM settings refreshes. Kill stale Unix claude-sidecar adapters processes before launching a new managed adapter sidecar so only one Telegram consumer remains active. Constraint: Telegram Bot API long polling should have a single active consumer for a token Rejected: Only restart the current tracked child | orphaned sidecars with PPID 1 are outside the tracked Tauri child handle Confidence: high Scope-risk: narrow Directive: Keep adapter sidecar startup single-instance across platforms when adding new IM adapters Tested: cargo fmt --check Tested: cargo check Tested: bun run check:native Tested: git diff --check Not-tested: Packaged macOS app relaunch with a real stale sidecar during automated test
This commit is contained in:
parent
54c975bc09
commit
c4d4568783
@ -1084,6 +1084,9 @@ fn stop_server_sidecar(app: &AppHandle) {
|
||||
/// 启动 adapter sidecar。返回 Result 主要为了把"无法 spawn"和"spawn 后立刻
|
||||
/// 退出(凭据缺失)"区分开 —— 后者不算错误,是正常 default 状态。
|
||||
fn start_adapters_sidecar(app: &AppHandle) -> Result<CommandChild, String> {
|
||||
#[cfg(unix)]
|
||||
kill_stale_unix_adapter_sidecars();
|
||||
|
||||
let app_root = resolve_app_root(app)?;
|
||||
let app_root_arg = app_root.to_string_lossy().to_string();
|
||||
|
||||
@ -1194,6 +1197,39 @@ fn stop_adapters_sidecar(app: &AppHandle) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn kill_stale_unix_adapter_sidecars() {
|
||||
let current_pid = std::process::id();
|
||||
let Ok(output) = StdCommand::new("ps")
|
||||
.args(["-axo", "pid=,command="])
|
||||
.output()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
for line in stdout.lines() {
|
||||
let mut parts = line.trim_start().splitn(2, char::is_whitespace);
|
||||
let Some(pid_text) = parts.next() else {
|
||||
continue;
|
||||
};
|
||||
let Some(command) = parts.next() else {
|
||||
continue;
|
||||
};
|
||||
let Ok(pid) = pid_text.parse::<u32>() else {
|
||||
continue;
|
||||
};
|
||||
if pid == current_pid {
|
||||
continue;
|
||||
}
|
||||
if !command.contains("claude-sidecar") || !command.contains(" adapters") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let _ = StdCommand::new("kill").arg(pid.to_string()).status();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn kill_windows_sidecars() {
|
||||
for image_name in [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user