Merge branch 'bugfix/stats-db-select' into 'dev'

Get rid of the stats database proxy

See merge request crafty-controller/crafty-4!276
This commit is contained in:
Andrew 2022-05-25 18:29:23 +00:00
commit b0b9936df7
2 changed files with 80 additions and 73 deletions

View File

@ -1,17 +1,18 @@
import os import os
import logging import logging
import datetime import datetime
import typing as t
from playhouse.shortcuts import model_to_dict
from app.classes.models.servers import Servers, HelperServers from app.classes.models.servers import Servers, HelperServers
from app.classes.shared.helpers import Helpers from app.classes.shared.helpers import Helpers
from app.classes.shared.main_models import DatabaseShortcuts
from app.classes.shared.migration import MigrationManager from app.classes.shared.migration import MigrationManager
try: try:
from peewee import ( from peewee import (
SqliteDatabase, SqliteDatabase,
Model, Model,
DatabaseProxy,
ForeignKeyField, ForeignKeyField,
CharField, CharField,
AutoField, AutoField,
@ -19,6 +20,7 @@ try:
BooleanField, BooleanField,
IntegerField, IntegerField,
FloatField, FloatField,
DoesNotExist,
) )
except ModuleNotFoundError as e: except ModuleNotFoundError as e:
@ -27,7 +29,6 @@ except ModuleNotFoundError as e:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
peewee_logger = logging.getLogger("peewee") peewee_logger = logging.getLogger("peewee")
peewee_logger.setLevel(logging.INFO) peewee_logger.setLevel(logging.INFO)
database_stats_proxy = DatabaseProxy()
# ********************************************************************************** # **********************************************************************************
@ -59,7 +60,6 @@ class ServerStats(Model):
class Meta: class Meta:
table_name = "server_stats" table_name = "server_stats"
database = database_stats_proxy
# ********************************************************************************** # **********************************************************************************
@ -70,7 +70,7 @@ class HelperServerStats:
self.database = database self.database = database
@staticmethod @staticmethod
def init_database(server_id): def init_database(server_id) -> t.Optional[SqliteDatabase]:
try: try:
server = HelperServers.get_server_data_by_id(server_id) server = HelperServers.get_server_data_by_id(server_id)
db_folder = os.path.join(f"{server['path']}", "db_stats") db_folder = os.path.join(f"{server['path']}", "db_stats")
@ -93,17 +93,17 @@ class HelperServerStats:
f"{helper_stats.migration_dir}", "stats" f"{helper_stats.migration_dir}", "stats"
) )
helper_stats.db_path = db_file helper_stats.db_path = db_file
database_stats_proxy.initialize(database)
migration_manager = MigrationManager(database, helper_stats) migration_manager = MigrationManager(database, helper_stats)
migration_manager.up() # Automatically runs migrations migration_manager.up() # Automatically runs migrations
database_stats_proxy.initialize(database) return database
except Exception as ex: except Exception as ex:
logger.warning( logger.warning(
f"Error try to look for the db_stats files for server : {ex}" f"Error try to look for the db_stats files for server : {ex}"
) )
return None
@staticmethod @staticmethod
def select_database(server_id): def select_database(server_id) -> t.Optional[SqliteDatabase]:
try: try:
server = HelperServers.get_server_data_by_id(server_id) server = HelperServers.get_server_data_by_id(server_id)
db_file = os.path.join( db_file = os.path.join(
@ -114,29 +114,25 @@ class HelperServerStats:
database = SqliteDatabase( database = SqliteDatabase(
db_file, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10} db_file, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
) )
database_stats_proxy.initialize(database) return database
except Exception as ex: except Exception as ex:
logger.warning( logger.warning(
f"Error try to look for the db_stats files for server : {ex}" f"Error try to look for the db_stats files for server : {ex}"
) )
return None
@staticmethod @staticmethod
def get_all_servers_stats(): def get_all_servers_stats():
servers = HelperServers.get_all_defined_servers() servers = HelperServers.get_all_defined_servers()
server_data = [] server_data = []
try: try:
for s in servers: for server in servers:
HelperServerStats.select_database(s.get("server_id")) stats = HelperServerStats.get_server_stats_by_id(server["server_id"])
latest = (
ServerStats.select()
.where(ServerStats.server_id == s.get("server_id"))
.order_by(ServerStats.created.desc())
.limit(1)
)
server_data.append( server_data.append(
{ {
"server_data": s, "server_data": server,
"stats": DatabaseShortcuts.return_rows(latest)[0], "stats": stats,
"user_command_permission": True, "user_command_permission": True,
} }
) )
@ -149,7 +145,7 @@ class HelperServerStats:
@staticmethod @staticmethod
def insert_server_stats(server): def insert_server_stats(server):
server_id = server.get("id", 0) server_id = server.get("id", 0)
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
if server_id == 0: if server_id == 0:
logger.warning("Stats saving failed with error: Server unknown (id = 0)") logger.warning("Stats saving failed with error: Server unknown (id = 0)")
@ -165,7 +161,7 @@ class HelperServerStats:
ServerStats.mem_percent: server.get("mem_percent", 0), ServerStats.mem_percent: server.get("mem_percent", 0),
ServerStats.world_name: server.get("world_name", ""), ServerStats.world_name: server.get("world_name", ""),
ServerStats.world_size: server.get("world_size", ""), ServerStats.world_size: server.get("world_size", ""),
ServerStats.server_port: server.get("server_port", ""), ServerStats.server_port: server.get("server_port", 0),
ServerStats.int_ping_results: server.get("int_ping_results", False), ServerStats.int_ping_results: server.get("int_ping_results", False),
ServerStats.online: server.get("online", False), ServerStats.online: server.get("online", False),
ServerStats.max: server.get("max", False), ServerStats.max: server.get("max", False),
@ -173,67 +169,73 @@ class HelperServerStats:
ServerStats.desc: server.get("desc", False), ServerStats.desc: server.get("desc", False),
ServerStats.version: server.get("version", False), ServerStats.version: server.get("version", False),
} }
).execute() ).execute(database)
@staticmethod @staticmethod
def remove_old_stats(server_id, last_week): def remove_old_stats(server_id, last_week):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
ServerStats.delete().where(ServerStats.created < last_week).execute() ServerStats.delete().where(ServerStats.created < last_week).execute(database)
@staticmethod @staticmethod
def get_latest_server_stats(server_id): def get_latest_server_stats(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
return ( return (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == server_id) .where(ServerStats.server_id == server_id)
.order_by(ServerStats.created.desc()) .order_by(ServerStats.created.desc())
.limit(1) .limit(1)
.execute(database)
) )
@staticmethod @staticmethod
def get_server_stats_by_id(server_id): def get_server_stats_by_id(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
stats = ( stats = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == server_id) .where(ServerStats.server_id == server_id)
.order_by(ServerStats.created.desc()) .order_by(ServerStats.created.desc())
.limit(1) .limit(1)
.first(database)
) )
return DatabaseShortcuts.return_rows(stats)[0] return model_to_dict(stats)
@staticmethod @staticmethod
def server_id_exists(server_id): def server_id_exists(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
if not HelperServers.get_server_data_by_id(server_id): # We can't use .exists because it doesn't seem to use the database parameter
return False return (
return True ServerStats.select()
.where(ServerStats.server_id == server_id)
.count(database)
!= 0
)
@staticmethod @staticmethod
def sever_crashed(server_id): def sever_crashed(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
ServerStats.update(crashed=True).where( ServerStats.update(crashed=True).where(
ServerStats.server_id == server_id ServerStats.server_id == server_id
).execute() ).execute(database)
@staticmethod @staticmethod
def set_download(server_id): def set_download(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
ServerStats.update(downloading=True).where( ServerStats.update(downloading=True).where(
ServerStats.server_id == server_id ServerStats.server_id == server_id
).execute() ).execute(database)
@staticmethod @staticmethod
def finish_download(server_id): def finish_download(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
ServerStats.update(downloading=False).where( ServerStats.update(downloading=False).where(
ServerStats.server_id == server_id ServerStats.server_id == server_id
).execute() ).execute(database)
@staticmethod @staticmethod
def get_download_status(server_id): def get_download_status(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
download_status = ( download_status = (
ServerStats.select().where(ServerStats.server_id == server_id).get() ServerStats.select().where(ServerStats.server_id == server_id).get(database)
) )
return download_status.downloading return download_status.downloading
@ -242,107 +244,109 @@ class HelperServerStats:
if server_id is None: if server_id is None:
return return
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
ServerStats.update(crashed=False).where( ServerStats.update(crashed=False).where(
ServerStats.server_id == server_id ServerStats.server_id == server_id
).execute() ).execute(database)
@staticmethod @staticmethod
def is_crashed(server_id): def is_crashed(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
svr = ServerStats.select().where(ServerStats.server_id == server_id).get() svr = (
# pylint: disable=singleton-comparison ServerStats.select().where(ServerStats.server_id == server_id).get(database)
if svr.crashed == True: )
return True return svr.crashed
else:
return False
@staticmethod @staticmethod
def set_update(server_id, value): def set_update(server_id, value):
if server_id is None: if server_id is None:
return return
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
try: try:
# Checks if server even exists # Checks if server even exists
ServerStats.select().where(ServerStats.server_id == server_id) ServerStats.select().where(ServerStats.server_id == server_id).execute(
except Exception as ex: database
)
except DoesNotExist as ex:
logger.error(f"Database entry not found! {ex}") logger.error(f"Database entry not found! {ex}")
return
ServerStats.update(updating=value).where( ServerStats.update(updating=value).where(
ServerStats.server_id == server_id ServerStats.server_id == server_id
).execute() ).execute(database)
@staticmethod @staticmethod
def get_update_status(server_id): def get_update_status(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
update_status = ( update_status = (
ServerStats.select().where(ServerStats.server_id == server_id).get() ServerStats.select().where(ServerStats.server_id == server_id).get(database)
) )
return update_status.updating return update_status.updating
@staticmethod @staticmethod
def set_first_run(server_id): def set_first_run(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
# Sets first run to false # Sets first run to false
try: try:
# Checks if server even exists # Checks if server even exists
ServerStats.select().where(ServerStats.server_id == server_id) ServerStats.select().where(ServerStats.server_id == server_id)
except Exception as ex: except DoesNotExist as ex:
logger.error(f"Database entry not found! {ex}") logger.error(f"Database entry not found! {ex}")
return return
ServerStats.update(first_run=False).where( ServerStats.update(first_run=False).where(
ServerStats.server_id == server_id ServerStats.server_id == server_id
).execute() ).execute(database)
@staticmethod @staticmethod
def get_first_run(server_id): def get_first_run(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
first_run = ServerStats.select().where(ServerStats.server_id == server_id).get() first_run = (
ServerStats.select().where(ServerStats.server_id == server_id).get(database)
)
return first_run.first_run return first_run.first_run
@staticmethod @staticmethod
def get_ttl_without_player(server_id): def get_ttl_without_player(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
last_stat = ( last_stat = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == server_id) .where(ServerStats.server_id == server_id)
.order_by(ServerStats.created.desc()) .order_by(ServerStats.created.desc())
.first() .first(database)
) )
last_stat_with_player = ( last_stat_with_player = (
ServerStats.select() ServerStats.select()
.where(ServerStats.server_id == server_id) .where(ServerStats.server_id == server_id)
.where(ServerStats.online > 0) .where(ServerStats.online > 0)
.order_by(ServerStats.created.desc()) .order_by(ServerStats.created.desc())
.first() .first(database)
) )
return last_stat.created - last_stat_with_player.created return last_stat.created - last_stat_with_player.created
@staticmethod @staticmethod
def can_stop_no_players(server_id, time_limit): def can_stop_no_players(server_id, time_limit):
HelperServerStats.select_database(server_id)
can = False
ttl_no_players = HelperServerStats.get_ttl_without_player(server_id) ttl_no_players = HelperServerStats.get_ttl_without_player(server_id)
if (time_limit == -1) or (ttl_no_players > time_limit): return (time_limit == -1) or (ttl_no_players > time_limit)
can = True
return can
@staticmethod @staticmethod
def set_waiting_start(server_id, value): def set_waiting_start(server_id, value):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
try: try:
# Checks if server even exists # Checks if server even exists
ServerStats.select().where(ServerStats.server_id == server_id) ServerStats.select().where(ServerStats.server_id == server_id).execute(
except Exception as ex: database
)
except DoesNotExist as ex:
logger.error(f"Database entry not found! {ex}") logger.error(f"Database entry not found! {ex}")
return
ServerStats.update(waiting_start=value).where( ServerStats.update(waiting_start=value).where(
ServerStats.server_id == server_id ServerStats.server_id == server_id
).execute() ).execute(database)
@staticmethod @staticmethod
def get_waiting_start(server_id): def get_waiting_start(server_id):
HelperServerStats.select_database(server_id) database = HelperServerStats.select_database(server_id)
waiting_start = ( waiting_start = (
ServerStats.select().where(ServerStats.server_id == server_id).get() ServerStats.select().where(ServerStats.server_id == server_id).get(database)
) )
return waiting_start.waiting_start return waiting_start.waiting_start

View File

@ -708,6 +708,7 @@ class Server:
) )
# cancel the watcher task # cancel the watcher task
self.server_scheduler.remove_job("c_" + str(self.server_id)) self.server_scheduler.remove_job("c_" + str(self.server_id))
self.server_scheduler.remove_job("stats_" + str(self.server_id))
return return
HelperServerStats.sever_crashed(self.server_id) HelperServerStats.sever_crashed(self.server_id)
@ -1137,6 +1138,7 @@ class Server:
"desc": raw_ping_result.get("desc"), "desc": raw_ping_result.get("desc"),
"version": raw_ping_result.get("version"), "version": raw_ping_result.get("version"),
"icon": raw_ping_result.get("icon"), "icon": raw_ping_result.get("icon"),
"crashed": self.is_crashed,
} }
) )
if len(self.helper.websocket_helper.clients) > 0: if len(self.helper.websocket_helper.clients) > 0:
@ -1161,6 +1163,7 @@ class Server:
"desc": raw_ping_result.get("desc"), "desc": raw_ping_result.get("desc"),
"version": raw_ping_result.get("version"), "version": raw_ping_result.get("version"),
"icon": raw_ping_result.get("icon"), "icon": raw_ping_result.get("icon"),
"crashed": self.is_crashed,
}, },
) )
total_players += int(raw_ping_result.get("online")) total_players += int(raw_ping_result.get("online"))