Load local sessions in the background for the Sessions popup
command_choose ran `herdr session list --json` (up to its 5 s timeout) before the popup drew anything, contradicting the documented immediate display. Run the listing on a worker thread and hand the selector a Future: the popup appears at once with a "… 本机 正在查询" placeholder, then fills in the local rows and any discovery warning when the result arrives, mirroring how remote hosts already load. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+16
-3
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from contextlib import contextmanager
|
||||
import curses
|
||||
from dataclasses import dataclass, field, replace
|
||||
@@ -1389,13 +1390,19 @@ def command_open(arguments: argparse.Namespace) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def local_session_listing(herdr_bin: str) -> tuple[list[str], list[str]]:
|
||||
"""Background half of the Sessions popup: names and warnings only."""
|
||||
report = discover_local_sessions(herdr_bin)
|
||||
return [endpoint.session for endpoint in report.endpoints], report.warnings
|
||||
|
||||
|
||||
def command_choose(arguments: argparse.Namespace) -> int:
|
||||
startup_warnings: list[str] = []
|
||||
hub = make_hub(arguments, warnings=startup_warnings)
|
||||
if not hub.exists():
|
||||
raise HubError("herdr-hub is not running")
|
||||
windows = hub.managed_windows()
|
||||
local_report = discover_local_sessions(resolve_herdr())
|
||||
herdr_bin = resolve_herdr()
|
||||
registry_warning = remember_remote_endpoints(
|
||||
window.endpoint for window in windows if window.endpoint is not None
|
||||
)
|
||||
@@ -1403,6 +1410,11 @@ def command_choose(arguments: argparse.Namespace) -> int:
|
||||
alias_registry = make_alias_registry()
|
||||
remote_registry = make_registry()
|
||||
ssh_bin = resolve_ssh()
|
||||
# `herdr session list` can take seconds; the popup must not wait for it.
|
||||
local_executor = ThreadPoolExecutor(
|
||||
max_workers=1, thread_name_prefix="herdr-hub-local"
|
||||
)
|
||||
local_future = local_executor.submit(local_session_listing, herdr_bin)
|
||||
|
||||
def close_window(window_id: str) -> list[CatalogWindow]:
|
||||
hub.dismiss_window(window_id)
|
||||
@@ -1519,15 +1531,14 @@ def command_choose(arguments: argparse.Namespace) -> int:
|
||||
catalog_windows(windows),
|
||||
remote_registry,
|
||||
ssh_bin,
|
||||
local_sessions=(endpoint.session for endpoint in local_report.endpoints),
|
||||
aliases=hub.aliases,
|
||||
activate_handler=activate_selection,
|
||||
rename_handler=rename_session,
|
||||
close_window_handler=close_window,
|
||||
delete_session_handler=delete_session,
|
||||
stop_session_handler=stop_session,
|
||||
pending_local_sessions=local_future,
|
||||
)
|
||||
startup_warnings.extend(local_report.warnings)
|
||||
if registry_warning:
|
||||
startup_warnings.append(registry_warning)
|
||||
if startup_warnings:
|
||||
@@ -1535,6 +1546,8 @@ def command_choose(arguments: argparse.Namespace) -> int:
|
||||
result = selector.run()
|
||||
except (RegistryError, SelectorError) as error:
|
||||
raise HubError(str(error)) from error
|
||||
finally:
|
||||
local_executor.shutdown(wait=False, cancel_futures=True)
|
||||
if result is None:
|
||||
return 0
|
||||
if result.kind == "rename":
|
||||
|
||||
Reference in New Issue
Block a user