Send a command to the daemon via socket.
(cmd: str, data: Dict = None, timeout: float = 60.0)
| 655 | |
| 656 | |
| 657 | def send_command(cmd: str, data: Dict = None, timeout: float = 60.0) -> Dict: |
| 658 | """Send a command to the daemon via socket.""" |
| 659 | if not SOCKET_FILE.exists(): |
| 660 | raise ConnectionError("Daemon socket not found. Is the daemon running?") |
| 661 | |
| 662 | sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) |
| 663 | sock.settimeout(timeout) |
| 664 | |
| 665 | try: |
| 666 | sock.connect(str(SOCKET_FILE)) |
| 667 | |
| 668 | # Send request |
| 669 | request = {"cmd": cmd, "data": data or {}} |
| 670 | sock.sendall(json.dumps(request).encode('utf-8')) |
| 671 | |
| 672 | # Receive response |
| 673 | response_data = b"" |
| 674 | while True: |
| 675 | chunk = sock.recv(65536) |
| 676 | if not chunk: |
| 677 | break |
| 678 | response_data += chunk |
| 679 | |
| 680 | if not response_data: |
| 681 | raise ConnectionError("No response from daemon. Connection closed.") |
| 682 | |
| 683 | response = json.loads(response_data.decode('utf-8')) |
| 684 | |
| 685 | # Check for error response |
| 686 | if response.get("status") == "error": |
| 687 | raise RuntimeError(response.get("message", "Unknown error")) |
| 688 | |
| 689 | return response |
| 690 | |
| 691 | except socket.timeout: |
| 692 | raise ConnectionError("Connection timed out. Daemon may be busy.") |
| 693 | except socket.error as e: |
| 694 | raise ConnectionError(f"Socket error: {e}. Is the daemon running?") |
| 695 | except json.JSONDecodeError as e: |
| 696 | raise RuntimeError(f"Invalid response from daemon: {e}") |
| 697 | finally: |
| 698 | try: |
| 699 | sock.close() |
| 700 | except: |
| 701 | pass |
| 702 | |
| 703 | |
| 704 | def daemon_status() -> Dict: |
no test coverage detected