From bf00ed75cf07d6c1fc9601bc8b369605e18d409a Mon Sep 17 00:00:00 2001 From: Till Immer Date: Sun, 4 Oct 2026 17:18:59 +0000 Subject: [PATCH] script-api.py aktualisiert --- script-api.py | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/script-api.py b/script-api.py index 490e30b..09fdc6c 100755 --- a/script-api.py +++ b/script-api.py @@ -2,10 +2,12 @@ import html import json +import queue import re import secrets import subprocess import sys +import threading import time import uuid @@ -910,6 +912,58 @@ class ApiHandler( +# ============================================================ +# Command execution queue +# ============================================================ + +COMMAND_QUEUE = queue.Queue() + + +def command_worker(): + while True: + job = COMMAND_QUEUE.get() + if job is None: + COMMAND_QUEUE.task_done() + break + + command_id, command, command_cfg, result_holder, finished = job + + try: + result_holder["result"] = _run_command_now( + command_id, + command, + command_cfg + ) + except subprocess.TimeoutExpired as exc: + result_holder["result"] = timeout_result( + command_id, + exc + ) + except Exception as exc: + result_holder["result"] = { + "ok": False, + "request_id": str(uuid.uuid4()), + "command_id": command_id, + "command": command, + "exit_code": None, + "timed_out": False, + "duration_ms": None, + "stdout": "", + "stderr": str(exc) + } + finally: + finished.set() + COMMAND_QUEUE.task_done() + + +COMMAND_WORKER = threading.Thread( + target=command_worker, + name="ir-command-worker", + daemon=True +) +COMMAND_WORKER.start() + + # ============================================================ # Command handling functions # ============================================================ @@ -1121,7 +1175,7 @@ def build_command( # Execute command # ============================================================ -def run_command( +def _run_command_now( command_id, command, command_cfg @@ -1257,6 +1311,41 @@ def run_command( +def run_command( + command_id, + command, + command_cfg +): + result_holder = {} + finished = threading.Event() + + queue_position = COMMAND_QUEUE.qsize() + 1 + + print( + f"Queued command_id={command_id} " + f"queue_position={queue_position} " + f"command={command}" + ) + + COMMAND_QUEUE.put( + ( + command_id, + command, + command_cfg, + result_holder, + finished + ) + ) + + # Wait until this command has finished. + # The HTTP API therefore keeps its existing synchronous behaviour, + # while the actual command execution is strictly serialized. + finished.wait() + + return result_holder["result"] + + + def timeout_result( command_id, exc