|
40 | 40 | from cms import config, get_safe_shard, ServiceCoord |
41 | 41 | from cms.io import Service, rpc_method |
42 | 42 |
|
| 43 | +from cms.db import SessionGen, Contest |
| 44 | +from sqlalchemy import select |
| 45 | + |
43 | 46 |
|
44 | 47 | logger = logging.getLogger(__name__) |
45 | 48 |
|
@@ -250,33 +253,29 @@ def _restart_services(self): |
250 | 253 | if proc is None or not proc.is_running(): |
251 | 254 | # We give contest_id even if the service doesn't need |
252 | 255 | # it, since it causes no trouble. |
| 256 | + |
| 257 | + active_contest_ids = self._get_active_contest_ids() |
| 258 | + |
253 | 259 | logger.info("Restarting (%s, %s)...", |
254 | 260 | service.name, service.shard) |
255 | 261 | command = os.path.join(BIN_PATH, "cms%s" % service.name) |
256 | 262 |
|
257 | | - MAX_AUTO_MAPPED_CONTESTS = 30 |
258 | | - |
259 | 263 |
|
260 | 264 | args = [command, "%d" % service.shard] |
261 | 265 |
|
262 | 266 | contest_specific_services = ["ContestWebServer", "ProxyService", "EvaluationService"] |
263 | 267 |
|
264 | 268 | if self.contest_id is not None: |
265 | 269 | if service.name in contest_specific_services: |
| 270 | + target_contest_id = service.shard + 1 |
266 | 271 |
|
267 | | - # *** ตรวจสอบว่า Shard ID อยู่ในขอบเขตที่เรามี Contest หรือไม่ *** |
268 | | - if service.shard < MAX_AUTO_MAPPED_CONTESTS: |
269 | | - derived_contest_id = service.shard + 1 |
270 | | - logger.info("Auto-mapping %s Shard %d to Contest ID %d (ignoring admin-selected ID %d)", |
271 | | - service.name, service.shard, derived_contest_id, self.contest_id) |
272 | | - args += ["-c", str(derived_contest_id)] |
273 | | - time.sleep(1) |
| 272 | + # *** ตรวจสอบว่า target_contest_id มีอยู่จริงใน Database หรือไม่ *** |
| 273 | + if target_contest_id in active_contest_ids: |
| 274 | + logger.info("Auto-mapping %s Shard %d to Active Contest ID %d", |
| 275 | + service.name, service.shard, target_contest_id) |
| 276 | + args += ["-c", str(target_contest_id)] |
274 | 277 | else: |
275 | | - # *** ถ้า Shard ID เกิน (เช่น Shard 4, 5, ...) ให้ข้ามไปเลย (continue) *** |
276 | | - #logger.warning("Skipping %s Shard %d: No auto-map contest ID available (Max: %d)", |
277 | | - # service.name, service.shard, MAX_AUTO_MAPPED_CONTESTS) |
278 | | - time.sleep(1) |
279 | | - continue # <-- นี่คือส่วนที่สำคัญที่สุด: สั่งให้ข้ามการ Restart |
| 278 | + continue |
280 | 279 | else: |
281 | 280 | args += ["-c", "ALL"] |
282 | 281 | try: |
@@ -500,3 +499,13 @@ def toggle_autorestart(self, service: str) -> bool | None: |
500 | 499 | service.name, service.shard, self._will_restart[service]) |
501 | 500 |
|
502 | 501 | return self._will_restart[service] |
| 502 | + def _get_active_contest_ids(self): |
| 503 | + """ดึง ID ของการแข่งขันทั้งหมดที่มีอยู่ในระบบจาก Database""" |
| 504 | + try: |
| 505 | + with SessionGen() as session: |
| 506 | + query = select(Contest.id) |
| 507 | + contest_ids = session.execute(query).scalars().all() |
| 508 | + return set(contest_ids) |
| 509 | + except Exception as e: |
| 510 | + logger.error("Failed to fetch contest IDs from DB: %s", e) |
| 511 | + return set() |
0 commit comments