From fe95a3b760a633f8d288ce0c055538fcb72b5cf8 Mon Sep 17 00:00:00 2001 From: Brett Williams Date: Mon, 10 Oct 2022 10:10:23 -0700 Subject: [PATCH] Save registered clients to server_state.json --- zordon_server.py | 85 +++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/zordon_server.py b/zordon_server.py index 92711c8..b83cda1 100755 --- a/zordon_server.py +++ b/zordon_server.py @@ -23,7 +23,7 @@ app = Flask(__name__) logger = logging.getLogger() local_hostname = socket.gethostname() -JSON_FILE = 'job_history.json' +JSON_FILE = 'server_state.json' #todo: move history to sqlite db @@ -142,63 +142,67 @@ class RenderServer: RenderStatus.COMPLETED, RenderStatus.ERROR]] for x in to_remove: x.archived = True + cls.save_state() @classmethod - def load_history(cls, json_path=None): + def load_state(cls, json_path=None): + """Load state history from JSON file""" input_path = json_path or JSON_FILE - if os.path.exists(input_path): - f = open(input_path) - job_list = json.load(f) - for job in job_list: + with open(input_path) as f: - # Identify renderer type and recreate Renderer object - job_render_object = RenderWorkerFactory.create_worker(job['renderer'], input_path=job['render']['input'], output_path=job['render']['output']) + # load saved data + saved_state = json.load(f) + cls.render_clients = saved_state.get('clients', {}) - # Load Renderer values - for key, val in job['render'].items(): - if val and key in ['start_time', 'end_time']: # convert date strings back into date objects - job_render_object.__dict__[key] = datetime.fromisoformat(val) - else: - job_render_object.__dict__[key] = val + for job in saved_state.get('jobs', []): - job_render_object.status = RenderStatus[job['status'].upper()] - job.pop('render', None) + # Identify renderer type and recreate Renderer object + job_render_object = RenderWorkerFactory.create_worker(job['renderer'], input_path=job['render']['input'], output_path=job['render']['output']) - # Create RenderJob with re-created Renderer object - new_job = RenderJob(job_render_object, job['priority'], job['client']) - for key, val in job.items(): - if key in ['date_created']: # convert date strings back to datetime objects - new_job.__dict__[key] = datetime.fromisoformat(val) - else: - new_job.__dict__[key] = val - new_job.__delattr__('status') + # Load Renderer values + for key, val in job['render'].items(): + if val and key in ['start_time', 'end_time']: # convert date strings back into date objects + job_render_object.__dict__[key] = datetime.fromisoformat(val) + else: + job_render_object.__dict__[key] = val - # Handle older loaded jobs that were cancelled before closing - if new_job.render_status() == RenderStatus.RUNNING: - new_job.render.status = RenderStatus.CANCELLED + job_render_object.status = RenderStatus[job['status'].upper()] + job.pop('render', None) - # finally add back to render queue - cls.render_queue.append(new_job) - f.close() + # Create RenderJob with re-created Renderer object + new_job = RenderJob(job_render_object, job['priority'], job['client']) + for key, val in job.items(): + if key in ['date_created']: # convert date strings back to datetime objects + new_job.__dict__[key] = datetime.fromisoformat(val) + else: + new_job.__dict__[key] = val + new_job.__delattr__('status') - cls.last_saved_counts = cls.job_counts() + # Handle older loaded jobs that were cancelled before closing + if new_job.render_status() == RenderStatus.RUNNING: + new_job.render.status = RenderStatus.CANCELLED + + # finally add back to render queue + cls.render_queue.append(new_job) + + cls.last_saved_counts = cls.job_counts() @classmethod - def save_history(cls, json_path=None): - """Save job history to JSON file""" + def save_state(cls, json_path=None): + """Save state history to JSON file""" try: logger.debug("Saving Render History") - new_list = [] - for job in cls.render_queue: - new_list.append(json.loads(job.json())) + output = {'timestamp': datetime.now().isoformat(), + 'jobs': [json.loads(j.json()) for j in cls.render_queue], + 'clients': cls.render_clients} output_path = json_path or JSON_FILE with open(output_path, 'w') as f: - json.dump(new_list, f, indent=4) + json.dump(output, f, indent=4) cls.last_saved_counts = cls.job_counts() except Exception as e: - logger.error("Error saving jobs JSON: {}".format(e)) + logger.error("Error saving state JSON: {}".format(e)) @classmethod def evaluate_queue(cls): @@ -222,7 +226,7 @@ class RenderServer: cls.start_job(job) if cls.last_saved_counts != cls.job_counts(): - cls.save_history() + cls.save_state() @classmethod def start_job(cls, job): @@ -289,6 +293,7 @@ class RenderServer: cls.render_clients.append(hostname) logger.info(f"Client '{hostname}' successfully registered") success = True + cls.save_state() except requests.ConnectionError as e: logger.error(f"Cannot connect to client at hostname: {hostname}") return success @@ -329,7 +334,7 @@ class RenderServer: flask_log.setLevel(config.get('flask_log_level', 'ERROR').upper()) # Setup the RenderServer object - cls.load_history() + cls.load_state() thread = threading.Thread(target=eval_loop, kwargs={'delay_sec': config.get('queue_eval_seconds', 1)}, daemon=True) thread.start()