mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-18 09:18:12 +00:00
Refactor: Move all initialization logic out of api_server and into init (#91)
* Zeroconf logging improvements * Ignore RuntimeErrors in background threads - Prevents issues during shutdown * Migrate start up code from api_server.py to init.py * Add error handlers to the API server to handle detached instances * Integrate RenderQueue eval loop into RenderQueue object * Silently catch RuntimeErrors on evaluate_queue * Stop background queue updates in prepare_for_shutdown
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.orm.exc import DetachedInstanceError
|
||||
|
||||
from src.utilities.status_utils import RenderStatus
|
||||
from src.engines.engine_manager import EngineManager
|
||||
from src.engines.core.base_worker import Base
|
||||
from src.utilities.status_utils import RenderStatus
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
@@ -17,6 +19,9 @@ class JobNotFoundError(Exception):
|
||||
super().__init__(args)
|
||||
self.job_id = job_id
|
||||
|
||||
def __str__(self):
|
||||
return f"Cannot find job with ID: {self.job_id}"
|
||||
|
||||
|
||||
class RenderQueue:
|
||||
engine = None
|
||||
@@ -24,9 +29,36 @@ class RenderQueue:
|
||||
job_queue = []
|
||||
maximum_renderer_instances = {'blender': 1, 'aerender': 1, 'ffmpeg': 4}
|
||||
last_saved_counts = {}
|
||||
is_running = False
|
||||
__eval_thread = None
|
||||
evaluation_inverval = 1
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
# --------------------------------------------
|
||||
# Start / Stop Background Updates
|
||||
# --------------------------------------------
|
||||
|
||||
@classmethod
|
||||
def start(cls):
|
||||
cls.is_running = True
|
||||
cls.__eval_thread = threading.Thread(target=cls.__eval_loop, daemon=True)
|
||||
cls.__eval_thread.start()
|
||||
|
||||
@classmethod
|
||||
def __eval_loop(cls):
|
||||
while cls.is_running:
|
||||
try:
|
||||
RenderQueue.evaluate_queue()
|
||||
except Exception as e:
|
||||
logger.exception(f"Uncaught error while evaluating queue: {e}")
|
||||
time.sleep(cls.evaluation_inverval)
|
||||
|
||||
@classmethod
|
||||
def stop(cls):
|
||||
cls.is_running = False
|
||||
|
||||
# --------------------------------------------
|
||||
# Queue Management
|
||||
# --------------------------------------------
|
||||
|
||||
@classmethod
|
||||
def add_to_render_queue(cls, render_job, force_start=False):
|
||||
@@ -89,6 +121,7 @@ class RenderQueue:
|
||||
@classmethod
|
||||
def prepare_for_shutdown(cls):
|
||||
logger.debug("Closing session")
|
||||
cls.stop()
|
||||
running_jobs = cls.jobs_with_status(RenderStatus.RUNNING) # cancel all running jobs
|
||||
[cls.cancel_job(job) for job in running_jobs]
|
||||
cls.save_state()
|
||||
@@ -105,19 +138,22 @@ class RenderQueue:
|
||||
|
||||
@classmethod
|
||||
def evaluate_queue(cls):
|
||||
not_started = cls.jobs_with_status(RenderStatus.NOT_STARTED, priority_sorted=True)
|
||||
for job in not_started:
|
||||
if cls.is_available_for_job(job.renderer, job.priority):
|
||||
cls.start_job(job)
|
||||
try:
|
||||
not_started = cls.jobs_with_status(RenderStatus.NOT_STARTED, priority_sorted=True)
|
||||
for job in not_started:
|
||||
if cls.is_available_for_job(job.renderer, job.priority):
|
||||
cls.start_job(job)
|
||||
|
||||
scheduled = cls.jobs_with_status(RenderStatus.SCHEDULED, priority_sorted=True)
|
||||
for job in scheduled:
|
||||
if job.scheduled_start <= datetime.now():
|
||||
logger.debug(f"Starting scheduled job: {job}")
|
||||
cls.start_job(job)
|
||||
scheduled = cls.jobs_with_status(RenderStatus.SCHEDULED, priority_sorted=True)
|
||||
for job in scheduled:
|
||||
if job.scheduled_start <= datetime.now():
|
||||
logger.debug(f"Starting scheduled job: {job}")
|
||||
cls.start_job(job)
|
||||
|
||||
if cls.last_saved_counts != cls.job_counts():
|
||||
cls.save_state()
|
||||
if cls.last_saved_counts != cls.job_counts():
|
||||
cls.save_state()
|
||||
except DetachedInstanceError:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def start_job(cls, job):
|
||||
|
||||
Reference in New Issue
Block a user