mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-23 19:32:24 +03:00
fix: remove background init timeout and allow skills reload retry
- Remove 5s thread.join() timeout so git clone/pull is not truncated - Remove _init_complete flag, reset _init_in_progress on failure instead - Let /reload/skills API retry initialization after network failure - Raise GIT_HTTP_LOW_SPEED_LIMIT from 1 KB/s to 10 KB/s Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
27051a89ad
commit
ae1a444677
@ -37,26 +37,13 @@ try:
|
|||||||
from .gns3_copilot.project_agent_manager import ProjectAgentManager
|
from .gns3_copilot.project_agent_manager import ProjectAgentManager
|
||||||
AI_COPILOT_AVAILABLE = True
|
AI_COPILOT_AVAILABLE = True
|
||||||
|
|
||||||
# Start skills repository initialization in background with 5s timeout.
|
# Start skills repository initialization in background.
|
||||||
# This clones/pulls GNS3-Skills during server startup.
|
# Clones/pulls GNS3-Skills during server startup.
|
||||||
# If GitHub is unreachable (common in some regions), the timeout
|
# Git network timeouts are configured in SkillsManager (_GIT_TIMEOUT_ENV).
|
||||||
# ensures the server starts without delay, using fallback defaults.
|
# The daemon thread auto-terminates when the process exits.
|
||||||
def _init_skills_background():
|
from gns3server.agent.gns3_copilot.skills.registry import _ensure_skills_manager
|
||||||
"""Initialize skills repo - called from background thread."""
|
|
||||||
from gns3server.agent.gns3_copilot.skills.registry import _ensure_skills_manager
|
|
||||||
|
|
||||||
t = threading.Thread(target=_ensure_skills_manager, daemon=True)
|
threading.Thread(target=_ensure_skills_manager, daemon=True).start()
|
||||||
t.start()
|
|
||||||
t.join(5)
|
|
||||||
if t.is_alive():
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
log.warning(
|
|
||||||
"Skills repository initialization timed out (5s). "
|
|
||||||
"Will use fallback defaults. "
|
|
||||||
"The background thread will complete when network is available."
|
|
||||||
)
|
|
||||||
|
|
||||||
threading.Thread(target=_init_skills_background, daemon=True).start()
|
|
||||||
|
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
# AI dependencies not installed, disable AI Copilot feature
|
# AI dependencies not installed, disable AI Copilot feature
|
||||||
|
|||||||
@ -51,7 +51,7 @@ logger = logging.getLogger(__name__)
|
|||||||
_GIT_TIMEOUT_ENV = {
|
_GIT_TIMEOUT_ENV = {
|
||||||
'GIT_HTTP_TIMEOUT': '10', # Connection timeout (default: 120s)
|
'GIT_HTTP_TIMEOUT': '10', # Connection timeout (default: 120s)
|
||||||
'GIT_HTTP_LOW_SPEED_TIME': '5', # Slow speed threshold window
|
'GIT_HTTP_LOW_SPEED_TIME': '5', # Slow speed threshold window
|
||||||
'GIT_HTTP_LOW_SPEED_LIMIT': '1000', # < 1 KB/s = slow → abort
|
'GIT_HTTP_LOW_SPEED_LIMIT': '10240', # < 10 KB/s = slow → abort
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -57,7 +57,6 @@ INJECTION_SKILLS_REGISTRY: dict[str, dict[str, Any]] = {}
|
|||||||
# Global skills manager instance for hot reload
|
# Global skills manager instance for hot reload
|
||||||
_skills_manager = None
|
_skills_manager = None
|
||||||
_init_in_progress = False
|
_init_in_progress = False
|
||||||
_init_complete = False
|
|
||||||
|
|
||||||
|
|
||||||
def set_skills_manager(manager):
|
def set_skills_manager(manager):
|
||||||
@ -75,16 +74,21 @@ def set_skills_manager(manager):
|
|||||||
|
|
||||||
def _ensure_skills_manager():
|
def _ensure_skills_manager():
|
||||||
"""
|
"""
|
||||||
Initialize the SkillsManager (runs once, idempotent).
|
Initialize the SkillsManager (idempotent, retryable on failure).
|
||||||
|
|
||||||
Reads config, creates SkillsManager, clones/pulls repo,
|
Reads config, creates SkillsManager, clones/pulls repo,
|
||||||
and loads skills/prompts into memory. Safe to call from
|
and loads skills/prompts into memory. Safe to call from
|
||||||
background threads - uses _init_in_progress to prevent
|
background threads - uses _init_in_progress to prevent
|
||||||
concurrent initialization.
|
concurrent initialization.
|
||||||
"""
|
|
||||||
global _skills_manager, _init_in_progress, _init_complete
|
|
||||||
|
|
||||||
if _skills_manager is not None or _init_complete:
|
On failure, resets _init_in_progress so future calls
|
||||||
|
(e.g., /reload/skills API) can retry. On success, the
|
||||||
|
manager is stored in _skills_manager and subsequent
|
||||||
|
calls return immediately.
|
||||||
|
"""
|
||||||
|
global _skills_manager, _init_in_progress
|
||||||
|
|
||||||
|
if _skills_manager is not None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if _init_in_progress:
|
if _init_in_progress:
|
||||||
@ -130,7 +134,7 @@ def _ensure_skills_manager():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error initializing skills manager: {e}", exc_info=True)
|
logger.error(f"Error initializing skills manager: {e}", exc_info=True)
|
||||||
finally:
|
finally:
|
||||||
_init_complete = True
|
_init_in_progress = False
|
||||||
|
|
||||||
|
|
||||||
def get_skills_manager():
|
def get_skills_manager():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user