mirror of
https://github.com/Tencent/BrowserSkill.git
synced 2026-09-10 13:01:23 +08:00
Widen session.start browser-connect wait for cold reconnects
After a long idle the service worker is only revived on its next keepalive-alarm tick (up to 30s away), so the previous 5s wait made the first command after idle fail with `no_browser_connected` even though the extension was about to reconnect. - Raise the daemon's `EXTENSION_CONNECT_WAIT` (used by `session.start`) to 35s so it comfortably covers one alarm period plus handshake slack. - Bump the CLI `session start` IPC timeout to that window plus slack so it never gives up before the daemon answers, and print a one-line "waiting for browser extension to connect…" hint when it actually waits. - Keep `bsk status` / `browsers` on their own short 5s wait so quick informational commands are not slowed down. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,10 +2,16 @@
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::daemon::browsers::EXTENSION_CONNECT_WAIT;
|
||||
|
||||
/// Default wait passed to daemon status/list RPCs when the registry is empty.
|
||||
pub const DEFAULT_BROWSER_CONNECT_WAIT: Duration = EXTENSION_CONNECT_WAIT;
|
||||
///
|
||||
/// Deliberately shorter than the daemon's [`EXTENSION_CONNECT_WAIT`]
|
||||
/// (used by `session.start`): `bsk status` / `bsk browsers` are quick
|
||||
/// informational snapshots, so blocking them for a full keepalive-alarm
|
||||
/// period would hurt more than it helps. The long wait is reserved for
|
||||
/// the command path that actually needs the extension online.
|
||||
///
|
||||
/// [`EXTENSION_CONNECT_WAIT`]: crate::daemon::browsers::EXTENSION_CONNECT_WAIT
|
||||
pub const DEFAULT_BROWSER_CONNECT_WAIT: Duration = Duration::from_secs(5);
|
||||
/// Keep CLI-side waits aligned with the daemon's IPC clamp so a bad env value
|
||||
/// cannot inflate read timeouts after the daemon has already returned.
|
||||
const MAX_BROWSER_CONNECT_WAIT: Duration = Duration::from_secs(60);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
//! structured JSON instead.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Context;
|
||||
@@ -17,9 +19,18 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::cli::ensure_daemon::ensure_daemon;
|
||||
use crate::cli::error::{self, CliError, Format, RenderExtras};
|
||||
use crate::daemon::browsers::EXTENSION_CONNECT_WAIT;
|
||||
|
||||
const SESSION_STOP_IPC_TIMEOUT: Duration = Duration::from_secs(60 * 60);
|
||||
|
||||
/// IPC read budget for `session.start`. The daemon holds this RPC open
|
||||
/// while it polls for the extension to (re)connect for up to
|
||||
/// [`EXTENSION_CONNECT_WAIT`], so the CLI-side timeout must exceed that
|
||||
/// window plus scheduling slack — otherwise the CLI would give up and
|
||||
/// surface a spurious timeout before the daemon ever answers.
|
||||
const SESSION_START_IPC_TIMEOUT: Duration =
|
||||
EXTENSION_CONNECT_WAIT.saturating_add(Duration::from_secs(10));
|
||||
|
||||
/// `bsk session …` subcommand tree.
|
||||
#[derive(Debug, Clone, Args)]
|
||||
pub struct SessionCmd {
|
||||
@@ -113,14 +124,31 @@ pub fn dispatch(cmd: SessionCmd, format: Format) -> Result<(), CliError> {
|
||||
}
|
||||
|
||||
fn run_start(sock: PathBuf, args: SessionStartArgs, format: Format) -> Result<(), CliError> {
|
||||
// The daemon may hold `session.start` open for up to
|
||||
// `EXTENSION_CONNECT_WAIT` while a just-woken service worker
|
||||
// reconnects. Let the user know we are waiting rather than hung —
|
||||
// but only if it actually takes a moment, so the common (already
|
||||
// connected) fast path stays silent. Human output only; the hint
|
||||
// goes to stderr so it never contaminates the session id on stdout.
|
||||
let waited = Arc::new(AtomicBool::new(false));
|
||||
if matches!(format, Format::Human) {
|
||||
let waited = Arc::clone(&waited);
|
||||
std::thread::spawn(move || {
|
||||
std::thread::sleep(Duration::from_millis(750));
|
||||
if !waited.swap(true, Ordering::SeqCst) {
|
||||
eprintln!("waiting for browser extension to connect…");
|
||||
}
|
||||
});
|
||||
}
|
||||
let result: Result<StartReply, CliError> = call(
|
||||
sock,
|
||||
Method::SessionStart,
|
||||
Some(StartParams {
|
||||
browser_instance_id: args.browser,
|
||||
}),
|
||||
Duration::from_secs(30),
|
||||
SESSION_START_IPC_TIMEOUT,
|
||||
);
|
||||
waited.store(true, Ordering::SeqCst);
|
||||
match result {
|
||||
Ok(reply) => match format {
|
||||
Format::Json => {
|
||||
|
||||
Reference in New Issue
Block a user