Internal implementation of find_all_game_folders with timeout
(base_dir: Path)
| 401 | |
| 402 | @timeout(120) |
| 403 | def _find_all_game_folders_impl(base_dir: Path) -> list[dict[str, Any]]: |
| 404 | """Internal implementation of find_all_game_folders with timeout""" |
| 405 | if not base_dir.exists(): |
| 406 | return [] |
| 407 | |
| 408 | # Find all metadata.json files directly |
| 409 | metadata_files = list(base_dir.rglob("metadata.json")) |
| 410 | |
| 411 | # Create folder info for each game folder |
| 412 | game_folder_infos = [] |
| 413 | |
| 414 | for metadata_file in metadata_files: |
| 415 | game_dir = metadata_file.parent |
| 416 | relative_path = str(game_dir.relative_to(base_dir)) |
| 417 | |
| 418 | # Extract parent folder path (folder containing the game folder) |
| 419 | parent_folder = str(game_dir.parent.relative_to(base_dir)) if game_dir.parent != base_dir else "" |
| 420 | |
| 421 | folder_info = { |
| 422 | "name": relative_path, |
| 423 | "full_path": str(game_dir), |
| 424 | "parent_folder": parent_folder, |
| 425 | } |
| 426 | game_folder_infos.append(folder_info) |
| 427 | |
| 428 | # Load metadata.json files in parallel |
| 429 | if game_folder_infos: |
| 430 | with ThreadPoolExecutor(max_workers=min(32, len(game_folder_infos))) as executor: |
| 431 | futures = { |
| 432 | executor.submit(_load_game_metadata, folder_info): folder_info for folder_info in game_folder_infos |
| 433 | } |
| 434 | for future in as_completed(futures): |
| 435 | try: |
| 436 | future.result() # Updates folder_info in place |
| 437 | except Exception as e: |
| 438 | # If metadata loading fails, set default values |
| 439 | folder_info = futures[future] |
| 440 | folder_info["round_info"] = None |
| 441 | folder_info["models"] = [] |
| 442 | folder_info["game_name"] = "" |
| 443 | folder_info["created_timestamp"] = None |
| 444 | logger.warning(f"Failed to load metadata for {folder_info['name']}: {e}") |
| 445 | |
| 446 | return sorted(game_folder_infos, key=lambda x: x["name"]) |
| 447 | |
| 448 | |
| 449 | @print_timing |