fix: real listener restart + remove listen_port editing from UI
Reviewer concerns: 1. POST /api/proxy/restart only saved config (reload), did not restart the listener. Now it touches data/restart.signal; proxy watcher polls that file separately and force-restarts the listener even when config is unchanged. 2. Editing proxy.listen_port via UI could break Docker port mapping (compose publishes 25565:25565 only). UI now shows it read-only; README documents how to change it together with compose. - proxy/main.py: ProxyState.check_restart_signal() + watcher uses it - api/config_io.py: touch_restart_signal() helper - api/routes/status.py: /api/proxy/restart -> touch_restart_signal() - frontend Settings: disabled listen_port input + 프록시 재시작 button - README + .gitignore updated
This commit is contained in:
@@ -20,6 +20,7 @@ import config as cfg_mod
|
||||
from handshake import HandshakeError, parse_handshake, read_handshake_bytes
|
||||
|
||||
LOG_DB = Path(os.environ.get("MC_LOG_DB", "/data/logs.db"))
|
||||
RESTART_SIGNAL = Path(os.environ.get("MC_RESTART_SIGNAL", "/data/restart.signal"))
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
@@ -76,10 +77,18 @@ def log_event(
|
||||
# ---------------------------------------------------------------------------
|
||||
# Runtime state
|
||||
# ---------------------------------------------------------------------------
|
||||
def _signal_mtime() -> float:
|
||||
try:
|
||||
return RESTART_SIGNAL.stat().st_mtime
|
||||
except FileNotFoundError:
|
||||
return 0.0
|
||||
|
||||
|
||||
class ProxyState:
|
||||
def __init__(self) -> None:
|
||||
self.cfg = cfg_mod.load()
|
||||
self.cfg_mtime = cfg_mod.mtime()
|
||||
self.signal_mtime = _signal_mtime()
|
||||
self.listen_port: int = int(self.cfg["proxy"]["listen_port"])
|
||||
|
||||
def allowed(self) -> set[str]:
|
||||
@@ -110,6 +119,15 @@ class ProxyState:
|
||||
log.warning("config reload failed: %s", exc)
|
||||
return False
|
||||
|
||||
def check_restart_signal(self) -> bool:
|
||||
"""`POST /api/proxy/restart` 가 touch 한 신호 파일 변경 여부."""
|
||||
m = _signal_mtime()
|
||||
if m == self.signal_mtime:
|
||||
return False
|
||||
self.signal_mtime = m
|
||||
log.info("restart signal received")
|
||||
return True
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# TCP tunneling
|
||||
@@ -249,11 +267,16 @@ async def config_watcher(state: ProxyState, listener: Listener) -> None:
|
||||
await asyncio.sleep(2)
|
||||
old_port = state.listen_port
|
||||
old_enabled = state.enabled()
|
||||
if not state.reload_if_changed():
|
||||
continue
|
||||
config_changed = state.reload_if_changed()
|
||||
signal_changed = state.check_restart_signal()
|
||||
|
||||
new_port = int(state.cfg["proxy"]["listen_port"])
|
||||
new_enabled = state.enabled()
|
||||
if new_port != old_port or new_enabled != old_enabled:
|
||||
|
||||
port_or_enabled_changed = (
|
||||
config_changed and (new_port != old_port or new_enabled != old_enabled)
|
||||
)
|
||||
if signal_changed or port_or_enabled_changed:
|
||||
state.listen_port = new_port
|
||||
await listener.restart()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user