From a2d1779e2bcbb9b89d0ea60207923a93fb71a092 Mon Sep 17 00:00:00 2001 From: n07070 Date: Wed, 3 Jun 2026 23:55:04 +0200 Subject: [PATCH] Update worker to get differents printer types --- src/worker.py | 114 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 36 deletions(-) diff --git a/src/worker.py b/src/worker.py index 5e5410f..e5a7fec 100644 --- a/src/worker.py +++ b/src/worker.py @@ -4,64 +4,105 @@ import threading import time +from printers import Printers class PrintWorker(threading.Thread): - def __init__(self, app, print_queue, printer, socketio=None): + def __init__(self, app, print_queue, socketio=None): super().__init__(daemon=True) self.app = app self.print_queue = print_queue - self.printer = printer + self.printer = None + self._lock = threading.Lock() self.socketio = socketio # Optional self.running = True self.state = "idle" # idle, printing, dead, drinking-a-beer - self.app.logger.debug("Ho great, I'm alive... I'm ready to work another day...") + try: + self.printers = Printers(self.app) + self.printers_obj = self.printers.printers + self.printers = iter(self.printers.printers) + except RuntimeError as e: + self.app.logger.warning("Could not get any Printers") + raise e + def run(self): """Background thread that processes queue items""" - self.app.logger.info("Worker started working.") + self.app.logger.debug("Worker %s started working.", threading.get_ident()) + self.app.logger.debug("Current threads : %s" % threading.active_count()) + self.app.logger.debug("Threads actives : %s " % threading.enumerate()) + while True: - if not self.running or not self.printer.ready: + + # If the printer is dead or asleep, it can't work. + if not self.running: time.sleep(0.2) continue - try: - task = self.print_queue.dequeue() - except Exception as e: - self.app.logger.error("Could not get a new task ! %s ", str(e)) - raise RuntimeError( - "We could not get a new task because " + str(e) - ) from e - - if task: + # If we have no available printer, we look at the list printers we know about, and try to find one that is available. + # When we find a printer, we acquire it + # When we are finished with a printer, we release it to the world. + while not self.printer or not self.printer.ready: + time.sleep(1) try: - self.app.logger.info("Got a new task") - self.app.logger.debug("Got task %s", task.task_id) - self.state = "printing" - task.status = "processing" - self._emit_status(task.task_id, "processing") + self.app.logger.debug("Changing printers") + self.printer = next(self.printers) + self.app.logger.debug("The worker got a %s printer and it's %s", self.printer.printer_type, "Ready" if self.printer.ready else "Not ready") + except Exception as e: + self.app.logger.error(str(e)) + self.printer = None - print_data = task.get_print_data() + if self.state != "idle": + self.app.logger("We are not idle, waiting...") + time.sleep(1) + continue + + self.state = "printing" + + with self._lock: + try: + task = self.print_queue.dequeue() + except Exception as e: + self.app.logger.error("Could not get a new task ! %s ", str(e)) + self.state = "idle" + raise RuntimeError( + "We could not get a new task because " + str(e) + ) from e + + if task: try: - self.printer.print_task(task.task_type, print_data) + self.app.logger.info("Got a new task") + self.app.logger.debug("Got task %s", task.task_id) + task.status = "processing" + self._emit_status(task.task_id, "processing") + + print_data = task.get_print_data() + + try: + self.printer.print_task(task.task_type, print_data) + except RuntimeError as e: + self.state = "idle" + self.app.logger.error("Could not print : %s", str(e)) + raise e + + task.status = "completed" + self.print_queue.mark_completed(task.task_id, "completed") + self._emit_status(task.task_id, "completed") + self.app.logger.debug("Finished printing task %s " % task.task_id) + self.state = "idle" + except RuntimeError as e: - self.app.logger.error("Could not print : %s", str(e)) - raise e + task.status = "failed" + self.state = "idle" + self.print_queue.mark_completed(task.task_id, "failed") + self._emit_status(task.task_id, "failed", error=str(e)) + self.app.logger.error("Could not print task %s because %s " % task.task_id, str(e)) - task.status = "completed" - self.print_queue.mark_completed(task.task_id, "completed") - self._emit_status(task.task_id, "completed") - - except RuntimeError as e: - task.status = "failed" - self.print_queue.mark_completed(task.task_id, "failed") - self._emit_status(task.task_id, "failed", error=str(e)) - print(f"Print task {task.task_id} failed: {e}") - else: - # When they are no new tasks to handle, we put the thread to sleep. - self.state = "idle" - time.sleep(0.1) + else: + # When they are no new tasks to handle, we put the thread to sleep. + self.state = "idle" + time.sleep(0.1) def _emit_status(self, task_id, status, error=None): """Emit status update via Socket.IO if available""" @@ -104,4 +145,5 @@ class PrintWorker(threading.Thread): "is_running": self.running, "queue_size": len(self.print_queue), "state": self.state, + "printers": len(self.printers_obj), }