clearml-server/apiserver/app_sequence.py
2021-01-05 16:45:22 +02:00

100 lines
3.2 KiB
Python

import atexit
from hashlib import md5
from flask import Flask
from semantic_version import Version
from apiserver.database import db
from apiserver.bll.statistics.stats_reporter import StatisticsReporter
from apiserver.config import info
from apiserver.config_repo import config
from apiserver.elastic.initialize import init_es_data, check_elastic_empty, ElasticConnectionError
from apiserver.mongo.initialize import (
init_mongo_data,
pre_populate_data,
check_mongo_empty,
get_last_server_version,
)
from apiserver.service_repo import ServiceRepo
from apiserver.sync import distributed_lock
from apiserver.updates import check_updates_thread
from apiserver.utilities.threads_manager import ThreadsManager
log = config.logger(__file__)
class AppSequence:
def __init__(self, app: Flask):
self.app = app
def start(self):
log.info("################ API Server initializing #####################")
self._configure()
self._init_dbs()
self._load_services()
self._start_worker()
atexit.register(self._on_worker_stop)
def _configure(self):
self.app.config["SECRET_KEY"] = config.get(
"secure.http.session_secret.apiserver"
)
self.app.config["JSONIFY_PRETTYPRINT_REGULAR"] = config.get(
"apiserver.pretty_json"
)
def _init_dbs(self):
db.initialize()
# build a key that uniquely identifies specific mongo instance
hosts_string = ";".join(sorted(db.get_hosts()))
key = "db_init_" + md5(hosts_string.encode()).hexdigest()
with distributed_lock(key, timeout=config.get("apiserver.db_init_timout", 120)):
upgrade_monitoring = config.get(
"apiserver.elastic.upgrade_monitoring.v16_migration_verification", True
)
try:
empty_es = check_elastic_empty()
except ElasticConnectionError as err:
if not upgrade_monitoring:
raise
log.error(err)
info.es_connection_error = True
empty_db = check_mongo_empty()
if (
upgrade_monitoring
and not empty_db
and (info.es_connection_error or empty_es)
and get_last_server_version() < Version("0.16.0")
):
log.info(f"ES database seems not migrated")
info.missed_es_upgrade = True
if info.es_connection_error and not info.missed_es_upgrade:
raise Exception(
"Error starting server: failed connecting to ElasticSearch service"
)
if not info.missed_es_upgrade:
init_es_data()
init_mongo_data()
if (
not info.missed_es_upgrade
and empty_db
and config.get("apiserver.pre_populate.enabled", False)
):
pre_populate_data()
def _load_services(self):
ServiceRepo.load("services")
log.info(f"Exposed Services: {' '.join(ServiceRepo.endpoint_names())}")
def _start_worker(self):
check_updates_thread.start()
StatisticsReporter.start()
def _on_worker_stop(self):
ThreadsManager.terminating = True