feat: on-demand RDP - connect xfreerdp only when session opens

Replaces always-on xfreerdp with on-demand model (load 12 to under 1 at idle).
- rdp-proxy/manager.py: HTTP server port 7001 managing xfreerdp lifecycle
- rdp-proxy/entrypoint.sh: starts Xvfb+x11vnc+websockify+manager, no auto-connect
- rdp-proxy/Dockerfile: adds python3, copies manager.py, exposes 7001
- runtime.py: connect_rdp_slot and disconnect_rdp_slot via manager HTTP API
- terminate_session_record: disconnect instead of container restart
- main.py: calls connect_rdp_slot in background thread on session create
- maintenance.py: cleanup_loop disconnects on expire, run_maintenance_service
  includes RDP slot init, maintenance_runner fixed to import maintenance
This commit is contained in:
2026-05-01 10:12:52 +00:00
parent 82024a36c4
commit 58cb8b1035
7 changed files with 204 additions and 72 deletions
+18 -2
View File
@@ -15,7 +15,7 @@ from utils import ensure_icons_dir, now_utc
from auth import hash_password
from runtime import (
_rdp_slot_container_name,
_restart_rdp_slot_bg,
disconnect_rdp_slot,
docker_client,
ensure_schema_compatibility,
ensure_universal_pool,
@@ -68,7 +68,7 @@ def cleanup_loop():
if stale:
db.commit()
for slot_id in rdp_slots_to_restart:
threading.Thread(target=_restart_rdp_slot_bg, args=(slot_id,), daemon=True).start()
threading.Thread(target=disconnect_rdp_slot, args=(slot_id,), daemon=True).start()
except Exception:
db.rollback()
logger.exception("cleanup_loop_failed")
@@ -140,6 +140,22 @@ def run_maintenance_service() -> None:
).all():
if svc.type == ServiceType.WEB and WEB_POOL_SIZE <= 0:
ensure_warm_pool(svc)
elif svc.type == ServiceType.RDP:
slots = db.scalars(select(RdpSlot).where(RdpSlot.service_id == svc.id)).all()
for slot in slots:
try:
cname = _rdp_slot_container_name(svc.slug, slot.id)
try:
c = docker_client().containers.get(cname)
if c.status != "running":
c.start()
except docker.errors.NotFound:
start_rdp_slot_container(slot, svc)
slot.container_name = cname
except Exception:
logger.exception("startup_rdp_slot_start_failed slot_id=%s", slot.id)
if slots:
db.commit()
finally:
db.close()