mirror of
https://github.com/blw1138/Zordon.git
synced 2026-02-05 05:36:09 +00:00
126 lines
5.3 KiB
Python
Executable File
126 lines
5.3 KiB
Python
Executable File
import logging
|
|
import multiprocessing
|
|
import os
|
|
import socket
|
|
import threading
|
|
from pathlib import Path
|
|
|
|
import psutil
|
|
|
|
from src.api.api_server import API_VERSION
|
|
from src.api.api_server import start_api_server
|
|
from src.api.preview_manager import PreviewManager
|
|
from src.api.serverproxy_manager import ServerProxyManager
|
|
from src.distributed_job_manager import DistributedJobManager
|
|
from src.engines.engine_manager import EngineManager
|
|
from src.render_queue import RenderQueue
|
|
from src.utilities.config import Config
|
|
from src.utilities.misc_helper import (get_gpu_info, current_system_cpu, current_system_os,
|
|
current_system_os_version, current_system_cpu_brand)
|
|
from src.utilities.zeroconf_server import ZeroconfServer
|
|
from src.version import APP_NAME, APP_VERSION
|
|
|
|
logger = logging.getLogger()
|
|
|
|
|
|
class ZordonServer:
|
|
|
|
def __init__(self):
|
|
# setup logging
|
|
logging.basicConfig(format='%(asctime)s: %(levelname)s: %(module)s: %(message)s', datefmt='%d-%b-%y %H:%M:%S',
|
|
level=Config.server_log_level.upper())
|
|
logging.getLogger("requests").setLevel(logging.WARNING) # suppress noisy requests/urllib3 logging
|
|
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
|
|
|
# Load Config YAML
|
|
Config.setup_config_dir()
|
|
config_path = Path(Config.config_dir()) / "config.yaml"
|
|
Config.load_config(config_path)
|
|
|
|
# configure default paths
|
|
EngineManager.engines_path = str(Path(Config.upload_folder).expanduser()/ "engines")
|
|
os.makedirs(EngineManager.engines_path, exist_ok=True)
|
|
PreviewManager.storage_path = Path(Config.upload_folder).expanduser() / "previews"
|
|
|
|
self.api_server = None
|
|
self.server_hostname: str = socket.gethostname()
|
|
|
|
def start_server(self):
|
|
|
|
def existing_process(process_name):
|
|
current_pid = os.getpid()
|
|
current_process = psutil.Process(current_pid)
|
|
for proc in psutil.process_iter(['pid', 'name', 'ppid']):
|
|
proc_name = proc.info['name'].lower().rstrip('.exe')
|
|
if proc_name == process_name.lower() and proc.info['pid'] != current_pid:
|
|
if proc.info['pid'] == current_process.ppid():
|
|
continue # parent process
|
|
elif proc.info['ppid'] == current_pid:
|
|
continue # child process
|
|
else:
|
|
return proc # unrelated process
|
|
return None
|
|
|
|
# check for existing instance
|
|
existing_proc = existing_process(APP_NAME)
|
|
if existing_proc:
|
|
err_msg = f"Another instance of {APP_NAME} is already running (pid: {existing_proc.pid})"
|
|
logger.fatal(err_msg)
|
|
raise ProcessLookupError(err_msg)
|
|
|
|
# main start
|
|
logger.info(f"Starting {APP_NAME} Render Server ({APP_VERSION})")
|
|
logger.debug(f"Upload directory: {Path(Config.upload_folder).expanduser()}")
|
|
logger.debug(f"Thumbs directory: {PreviewManager.storage_path}")
|
|
logger.debug(f"Engines directory: {EngineManager.engines_path}")
|
|
# Set up the RenderQueue object
|
|
RenderQueue.load_state(database_directory=Path(Config.upload_folder).expanduser())
|
|
ServerProxyManager.subscribe_to_listener()
|
|
DistributedJobManager.subscribe_to_listener()
|
|
|
|
# update hostname
|
|
self.server_hostname = socket.gethostname()
|
|
|
|
# configure and start API server
|
|
self.api_server = threading.Thread(target=start_api_server, args=(self.server_hostname,))
|
|
self.api_server.daemon = True
|
|
self.api_server.start()
|
|
|
|
# start zeroconf server
|
|
ZeroconfServer.configure(f"_{APP_NAME.lower()}._tcp.local.", self.server_hostname, Config.port_number)
|
|
ZeroconfServer.properties = {'system_cpu': current_system_cpu(),
|
|
'system_cpu_brand': current_system_cpu_brand(),
|
|
'system_cpu_cores': multiprocessing.cpu_count(),
|
|
'system_os': current_system_os(),
|
|
'system_os_version': current_system_os_version(),
|
|
'system_memory': round(psutil.virtual_memory().total / (1024**3)), # in GB
|
|
'gpu_info': get_gpu_info(),
|
|
'api_version': API_VERSION}
|
|
ZeroconfServer.start()
|
|
logger.info(f"{APP_NAME} Render Server started - Hostname: {self.server_hostname}")
|
|
RenderQueue.start() # Start evaluating the render queue
|
|
|
|
def is_running(self):
|
|
return self.api_server and self.api_server.is_alive()
|
|
|
|
def stop_server(self):
|
|
logger.info(f"{APP_NAME} Render Server is preparing to stop")
|
|
try:
|
|
ZeroconfServer.stop()
|
|
RenderQueue.prepare_for_shutdown()
|
|
except Exception as e:
|
|
logger.exception(f"Exception during prepare for shutdown: {e}")
|
|
logger.info(f"{APP_NAME} Render Server has shut down")
|
|
|
|
if __name__ == '__main__':
|
|
server = ZordonServer()
|
|
try:
|
|
server.start_server()
|
|
server.api_server.join()
|
|
except KeyboardInterrupt:
|
|
pass
|
|
except Exception as e:
|
|
logger.fatal(f"Unhandled exception: {e}")
|
|
finally:
|
|
server.stop_server()
|