diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index 88423e8b6d..34bf57594d 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -1,6 +1,7 @@ SUBSYSTEM_DEF(dbcore) name = "Database" - flags = SS_NO_FIRE + flags = SS_BACKGROUND + wait = 1 MINUTES init_order = INIT_ORDER_DBCORE var/const/FAILED_DB_CONNECTION_CUTOFF = 5 @@ -25,6 +26,8 @@ SUBSYSTEM_DEF(dbcore) var/_db_con// This variable contains a reference to the actual database connection. var/failed_connections = 0 + var/list/active_queries = list() + /datum/controller/subsystem/dbcore/PreInit() if(!_db_con) _db_con = _dm_db_new_con() @@ -40,6 +43,15 @@ SUBSYSTEM_DEF(dbcore) return ..() +/datum/controller/subsystem/dbcore/fire() + for(var/I in active_queries) + var/datum/DBQuery/Q = I + if(world.time - Q.last_activity_time > (5 MINUTES)) + message_admins("Found undeleted query, please check the server logs and notify coders.") + log_sql("Undeleted query: \"[Q.sql]\" LA: [Q.last_activity] LAT: [Q.last_activity_time]") + qdel(Q) + if(MC_TICK_CHECK) + return /datum/controller/subsystem/dbcore/Recover() _db_con = SSdbcore._db_con @@ -49,12 +61,13 @@ SUBSYSTEM_DEF(dbcore) if(SSdbcore.Connect()) var/datum/DBQuery/query_round_shutdown = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = '[sanitizeSQL(SSticker.end_state)]' WHERE id = [GLOB.round_id]") query_round_shutdown.Execute() + qdel(query_round_shutdown) if(IsConnected()) Disconnect() //nu /datum/controller/subsystem/dbcore/can_vv_get(var_name) - return var_name != "_db_con" && ..() + return var_name != NAMEOF(src, _db_con) && var_name != NAMEOF(src, active_queries) && ..() /datum/controller/subsystem/dbcore/vv_edit_var(var_name, var_value) if(var_name == "_db_con") @@ -98,33 +111,38 @@ SUBSYSTEM_DEF(dbcore) else schema_mismatch = 2 //flag admin message about no schema version log_sql("Could not get schema version from database") + qdel(query_db_version) else log_sql("Your server failed to establish a connection with the database.") else log_sql("Database is not enabled in configuration.") /datum/controller/subsystem/dbcore/proc/SetRoundID() - if(CONFIG_GET(flag/sql_enabled)) - if(SSdbcore.Connect()) - var/datum/DBQuery/query_round_initialize = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')") - query_round_initialize.Execute() - var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()") - query_round_last_id.Execute() - if(query_round_last_id.NextRow()) - GLOB.round_id = query_round_last_id.item[1] + if(!Connect()) + return + var/datum/DBQuery/query_round_initialize = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')") + query_round_initialize.Execute() + qdel(query_round_initialize) + var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()") + query_round_last_id.Execute() + if(query_round_last_id.NextRow()) + GLOB.round_id = query_round_last_id.item[1] + qdel(query_round_last_id) /datum/controller/subsystem/dbcore/proc/SetRoundStart() - if(CONFIG_GET(flag/sql_enabled)) - if(SSdbcore.Connect()) - var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = [GLOB.round_id]") - query_round_start.Execute() + if(!Connect()) + return + var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = [GLOB.round_id]") + query_round_start.Execute() + qdel(query_round_start) /datum/controller/subsystem/dbcore/proc/SetRoundEnd() - if(CONFIG_GET(flag/sql_enabled)) - if(SSdbcore.Connect()) - var/sql_station_name = sanitizeSQL(station_name()) - var/datum/DBQuery/query_round_end = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = '[sanitizeSQL(SSticker.mode_result)]', station_name = '[sql_station_name]' WHERE id = [GLOB.round_id]") - query_round_end.Execute() + if(!Connect()) + return + var/sql_station_name = sanitizeSQL(station_name()) + var/datum/DBQuery/query_round_end = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = '[sanitizeSQL(SSticker.mode_result)]', station_name = '[sql_station_name]' WHERE id = [GLOB.round_id]") + query_round_end.Execute() + qdel(query_round_end) /datum/controller/subsystem/dbcore/proc/Disconnect() failed_connections = 0 @@ -212,9 +230,10 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table sqlrowlist = " [sqlrowlist.Join(",\n ")]" var/datum/DBQuery/Query = NewQuery("INSERT[delayed][ignore_errors] INTO [table]\n([columns.Join(", ")])\nVALUES\n[sqlrowlist]\n[duplicate_key]") if (warn) - return Query.warn_execute() + . = Query.warn_execute() else - return Query.Execute() + . = Query.Execute() + qdel(Query) /datum/DBQuery @@ -223,11 +242,14 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table var/list/columns //list of DB Columns populated by Columns() var/list/conversions var/list/item //list of data values populated by NextRow() - + var/last_activity + var/last_activity_time var/datum/controller/subsystem/dbcore/db_connection var/_db_query /datum/DBQuery/New(sql_query, datum/controller/subsystem/dbcore/connection_handler, cursor_handler) + SSdbcore.active_queries[src] = TRUE + Activity("Created") if(sql_query) sql = sql_query if(connection_handler) @@ -261,6 +283,7 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table sql = new_sql /datum/DBQuery/proc/Execute(sql_query = sql, cursor_handler = default_cursor, log_error = TRUE) + Activity("Execute") var/start_time var/timeout = CONFIG_GET(number/query_debug_log_timeout) if(timeout) @@ -281,6 +304,7 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table message_admins("HEY! A database query may have timed out. Did the server just hang? \[YES\]|\[NO\]") /datum/DBQuery/proc/NextRow() + Activity("NextRow") return _dm_db_next_row(_db_query,item,conversions) /datum/DBQuery/proc/RowsAffected() diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 1769a26d18..a62755eb5f 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -96,7 +96,7 @@ if(sig_type[1] == "!") SSdcs.RegisterSignal(src, sig_type) - + procs[sig_type] = proc_or_callback enabled = TRUE