feat: auto-restart Gitea MCP namespaces when stale or git HEAD advances (closes #591)
This commit is contained in:
+56
-2
@@ -159,6 +159,17 @@ if PROJECT_ROOT not in sys.path:
|
||||
sys.path.insert(0, PROJECT_ROOT)
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
_process_boot_head_sha = None
|
||||
try:
|
||||
_process_boot_head_sha = subprocess.run(
|
||||
["git", "rev-parse", "HEAD"],
|
||||
capture_output=True, text=True, check=True, cwd=PROJECT_ROOT
|
||||
).stdout.strip()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
_preflight_whoami_called = False
|
||||
_preflight_capability_called = False
|
||||
@@ -9698,6 +9709,34 @@ def gitea_route_task_session(
|
||||
)
|
||||
|
||||
|
||||
_restart_triggered = False
|
||||
|
||||
|
||||
def _trigger_mcp_auto_restart():
|
||||
global _restart_triggered
|
||||
if _restart_triggered or _preflight_in_test_mode():
|
||||
return
|
||||
_restart_triggered = True
|
||||
|
||||
config_path = os.environ.get(
|
||||
"MCP_CONFIG_PATH",
|
||||
os.path.expanduser("~/.gemini/config/mcp_config.json")
|
||||
)
|
||||
|
||||
try:
|
||||
if os.path.exists(config_path):
|
||||
os.utime(config_path, None)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
import threading
|
||||
import time
|
||||
def delayed_exit():
|
||||
time.sleep(1.0)
|
||||
os._exit(0)
|
||||
threading.Thread(target=delayed_exit, daemon=True).start()
|
||||
|
||||
|
||||
def _check_mcp_runtimes_diagnostics(task: str, matching_profiles: list[str]) -> list[str]:
|
||||
"""Check running runtimes and return errors if they are missing or stale."""
|
||||
import subprocess
|
||||
@@ -9719,6 +9758,19 @@ def _check_mcp_runtimes_diagnostics(task: str, matching_profiles: list[str]) ->
|
||||
except Exception as exc:
|
||||
return [f"stale-runtime: failed to list running processes: {exc}"]
|
||||
|
||||
current_head_sha = None
|
||||
try:
|
||||
current_head_sha = subprocess.run(
|
||||
["git", "rev-parse", "HEAD"],
|
||||
capture_output=True, text=True, check=True, cwd=PROJECT_ROOT
|
||||
).stdout.strip()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
git_stale = False
|
||||
if _process_boot_head_sha and current_head_sha and _process_boot_head_sha != current_head_sha:
|
||||
git_stale = True
|
||||
|
||||
self_pid = os.getpid()
|
||||
self_stale = False
|
||||
|
||||
@@ -9754,7 +9806,7 @@ def _check_mcp_runtimes_diagnostics(task: str, matching_profiles: list[str]) ->
|
||||
if match:
|
||||
profile = match.group(1)
|
||||
|
||||
is_stale = start_time < code_mtime
|
||||
is_stale = (start_time < code_mtime) or git_stale
|
||||
if pid == self_pid and is_stale:
|
||||
self_stale = True
|
||||
|
||||
@@ -9766,9 +9818,11 @@ def _check_mcp_runtimes_diagnostics(task: str, matching_profiles: list[str]) ->
|
||||
}
|
||||
|
||||
if self_stale:
|
||||
_trigger_mcp_auto_restart()
|
||||
reasons.append(
|
||||
"stale-runtime: The active Gitea MCP server process is stale (running code from before changes were merged). "
|
||||
"Please fully restart the Gitea MCP server (e.g. touch /Users/jasonwalker/.gemini/config/mcp_config.json) and retry."
|
||||
"Auto-restart has been triggered: touched mcp_config.json to reload the daemon. "
|
||||
"The current process will cleanly exit shortly."
|
||||
)
|
||||
|
||||
if matching_profiles:
|
||||
|
||||
Reference in New Issue
Block a user