Run multiple gates concurrently, retrying until all pass. Returns the number of gates that passed.
(gates: list[dict])
| 386 | |
| 387 | |
| 388 | def run_gates_concurrent(gates: list[dict]) -> int: |
| 389 | """Run multiple gates concurrently, retrying until all pass. |
| 390 | |
| 391 | Returns the number of gates that passed. |
| 392 | """ |
| 393 | nums = ", ".join(str(g["num"]) for g in gates) |
| 394 | total = len(GATES) |
| 395 | |
| 396 | print(f" {CYAN}{BOLD}{'=' * 60}{RESET}") |
| 397 | print(f" {CYAN}{BOLD} GATES {nums} (CONCURRENT):{RESET}") |
| 398 | for g in gates: |
| 399 | proto = "https" if g["port"] == 443 else "http" |
| 400 | print( |
| 401 | f" {DIM} Gate {g['num']}: {g['name']} " |
| 402 | f"{proto}://{g['host']}:{g['port']}{RESET}" |
| 403 | ) |
| 404 | print(f" {CYAN}{BOLD}{'=' * 60}{RESET}") |
| 405 | print() |
| 406 | |
| 407 | log( |
| 408 | "INFO", |
| 409 | f"Firing {len(gates)} requests concurrently -- approve them all at once", |
| 410 | ) |
| 411 | log("INFO", "Tip: press [A] in the TUI draft panel to approve all pending") |
| 412 | print() |
| 413 | |
| 414 | remaining_gates = list(gates) |
| 415 | |
| 416 | for attempt in range(1, MAX_RETRIES + 1): |
| 417 | log( |
| 418 | "GATE", |
| 419 | f"Concurrent attempt #{attempt}", |
| 420 | pending=len(remaining_gates), |
| 421 | ) |
| 422 | |
| 423 | # Fire all remaining gates concurrently. |
| 424 | results: dict[int, tuple[str, str]] = {} |
| 425 | threads: list[threading.Thread] = [] |
| 426 | |
| 427 | def _attempt(g: dict) -> None: |
| 428 | results[g["num"]] = attempt_gate(g) |
| 429 | |
| 430 | for g in remaining_gates: |
| 431 | t = threading.Thread(target=_attempt, args=(g,)) |
| 432 | threads.append(t) |
| 433 | t.start() |
| 434 | |
| 435 | for t in threads: |
| 436 | t.join(timeout=30) |
| 437 | |
| 438 | # Process results. |
| 439 | still_blocked = [] |
| 440 | for g in remaining_gates: |
| 441 | num = g["num"] |
| 442 | status, result = results.get(num, ("blocked", "no result")) |
| 443 | |
| 444 | if status == "pass": |
| 445 | log("PASS", f"Gate {num}/{total} UNLOCKED ({g['name']})") |