fix: RDP slot occupancy and cleanup_loop always running

- admin_page: slot shown as occupied based on ACTIVE status only (no time cutoff)
- go_service: busy slots checked by ACTIVE status (no cutoff) — cleanup_loop handles expiry
- startup_event: cleanup_loop starts regardless of ENABLE_STARTUP_MAINTENANCE flag;
  pool/container init guarded by the flag separately
- cleanup_loop: RDPSLOT sessions expire correctly and trigger container restart

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-28 06:48:00 +00:00
parent 552898e3e9
commit a4a96c45b0
+8 -8
View File
@@ -1742,13 +1742,11 @@ def startup_event():
fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
ensure_icons_dir()
bootstrap_admin()
if not ENABLE_STARTUP_MAINTENANCE:
logger.info("startup_maintenance_disabled")
return
if not try_acquire_maintenance_leader():
logger.info("maintenance_leader_skipped")
return
if ENABLE_STARTUP_MAINTENANCE:
db = SessionLocal()
try:
ensure_universal_pool()
@@ -1765,8 +1763,14 @@ def startup_event():
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 = _rdp_slot_container_name(svc.slug, slot.id)
slot.container_name = cname
except Exception:
logger.exception("startup_rdp_slot_start_failed slot_id=%s", slot.id)
if slots:
@@ -1953,7 +1957,6 @@ def admin_page(request: Request, admin: User = Depends(require_admin), db: Sessi
{"cutoff": cutoff},
).mappings().all()
rdp_slots: dict[int, list] = {}
cutoff_slot = now_utc() - dt.timedelta(seconds=SESSION_IDLE_SECONDS)
for svc in rdp_services:
slots = db.scalars(select(RdpSlot).where(RdpSlot.service_id == svc.id).order_by(RdpSlot.id)).all()
slot_list = []
@@ -1962,7 +1965,6 @@ def admin_page(request: Request, admin: User = Depends(require_admin), db: Sessi
select(SessionModel).where(
SessionModel.container_id == f"RDPSLOT:{slot.id}",
SessionModel.status == SessionStatus.ACTIVE,
SessionModel.last_access_at >= cutoff_slot,
)
)
running = False
@@ -2162,12 +2164,10 @@ def go_service(
session_id = str(uuid.uuid4())
try:
with allocator_lock(db, 91003, timeout_seconds=GO_POOL_LOCK_TIMEOUT_SECONDS):
cutoff = now_utc() - dt.timedelta(seconds=SESSION_IDLE_SECONDS)
busy_slot_ids: set[int] = set()
for row in db.scalars(
select(SessionModel).where(
SessionModel.status == SessionStatus.ACTIVE,
SessionModel.last_access_at >= cutoff,
SessionModel.service_id == service.id,
SessionModel.container_id.like("RDPSLOT:%"),
)