Main daemon loop: process package installation requests.
()
| 779 | |
| 780 | |
| 781 | def run_daemon_loop() -> None: |
| 782 | """Main daemon loop: process package installation requests.""" |
| 783 | global _daemon_pid, _daemon_started_at |
| 784 | |
| 785 | # Register signal handlers |
| 786 | signal.signal(signal.SIGTERM, signal_handler) |
| 787 | signal.signal(signal.SIGINT, signal_handler) |
| 788 | |
| 789 | # Initialize daemon tracking variables |
| 790 | _daemon_pid = os.getpid() |
| 791 | _daemon_started_at = time.time() |
| 792 | |
| 793 | # Initialize build process tracker |
| 794 | build_tracker = BuildProcessTracker(BUILD_REGISTRY_FILE) |
| 795 | |
| 796 | logging.info(f"Daemon started with PID {_daemon_pid}") |
| 797 | update_status(DaemonState.IDLE, "Daemon ready") |
| 798 | |
| 799 | last_activity = time.time() |
| 800 | last_orphan_check = time.time() |
| 801 | |
| 802 | while True: |
| 803 | try: |
| 804 | # Check for shutdown signal |
| 805 | if should_shutdown(): |
| 806 | cleanup_and_exit() |
| 807 | |
| 808 | # Check idle timeout |
| 809 | if time.time() - last_activity > IDLE_TIMEOUT: |
| 810 | logging.info(f"Idle timeout reached ({IDLE_TIMEOUT}s), shutting down") |
| 811 | cleanup_and_exit() |
| 812 | |
| 813 | # Periodically check for and cleanup orphaned build processes |
| 814 | if time.time() - last_orphan_check >= ORPHAN_CHECK_INTERVAL: |
| 815 | try: |
| 816 | orphaned_clients = build_tracker.cleanup_orphaned_processes() |
| 817 | if orphaned_clients: |
| 818 | logging.info( |
| 819 | f"Cleaned up orphaned processes for {len(orphaned_clients)} dead clients: {orphaned_clients}" |
| 820 | ) |
| 821 | last_orphan_check = time.time() |
| 822 | except KeyboardInterrupt as ki: |
| 823 | handle_keyboard_interrupt(ki) |
| 824 | raise |
| 825 | except Exception as e: |
| 826 | logging.error(f"Error during orphan cleanup: {e}", exc_info=True) |
| 827 | |
| 828 | # Check for new requests |
| 829 | request = read_request_file() |
| 830 | if request: |
| 831 | logging.info(f"Received request: {request}") |
| 832 | |
| 833 | # CHECK: Refuse if installation already in progress |
| 834 | with _installation_lock: |
| 835 | if _installation_in_progress: |
| 836 | # Read current status to get active caller info |
| 837 | current_status = read_status_file_safe() |
| 838 | active_pid = current_status.caller_pid or "unknown" |
no test coverage detected