[MIRROR] Significantly speed up create & destroy by reducing the amount of time to wait for GC [MDB IGNORE] (#20459)

* Significantly speed up create & destroy by reducing the amount of time to wait for GC (#74604)

The check queue is 5 minutes long because that's the longest a client
can hold onto a reference. Without clients, we can drastically decrease
the time we have to wait. This lowers the time down to 10 seconds
(though everything right now deletes in 5).

This will represent a 5 minute decrease in CI across the board, freeing
up runners.

Makes a few changes to stuff that was being held for more than 10
seconds.
- `VARSET_CALLBACK` now works through weakrefs, to allow for pAIs to
have their holochassis init timers.
- Nar'Sie cleans herself up in GLOB.cult_narsie if she's deleted.
- "Spooky portals" no longer hold onto a reference for 2 minutes.
- `poll_candidates` short circuits to an empty list if there are no
candidates, to avoid several 30 second+ long timers

Originally this was going to be a more clever hack from @ MrStonedOne
about short circuiting if everything deletes before the wait, but we
realized that basically nothing actually holds onto references for that
long without clients, and that nothing really should anyway

* Significantly speed up create & destroy by reducing the amount of time to wait for GC

---------

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-04-09 19:36:44 -07:00
committed by GitHub
co-authored by Mothblocks
parent 4724eb4bec
commit 6a9036149c
7 changed files with 28 additions and 5 deletions
+3
View File
@@ -238,6 +238,9 @@
///Calls the show_candidate_poll_window() to all eligible ghosts
/proc/poll_candidates(question, jobban_type, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null)
if (group.len == 0)
return list()
var/time_passed = world.time
if (!question)
question = "Would you like to be a special role?"
+11
View File
@@ -1,12 +1,23 @@
#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), ##target, ##var_name, ##var_value)
//dupe code because dm can't handle 3 level deep macros
#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), ##datum, NAMEOF(##datum, ##var), ##var_value)
/// Same as VARSET_CALLBACK, but uses a weakref to the datum.
/// Use this if the timer is exceptionally long.
#define VARSET_WEAK_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), WEAKREF(##datum), NAMEOF(##datum, ##var), ##var_value)
/proc/___callbackvarset(list_or_datum, var_name, var_value)
if(length(list_or_datum))
list_or_datum[var_name] = var_value
return
var/datum/datum = list_or_datum
if (isweakref(datum))
var/datum/weakref/datum_weakref = datum
datum = datum_weakref.resolve()
if (isnull(datum))
return
if(IsAdminAdvancedProcCall())
datum.vv_edit_var(var_name, var_value) //same result generally, unless badmemes
else
@@ -147,7 +147,7 @@
START_PROCESSING(SSobj, src)
INVOKE_ASYNC(src, PROC_REF(make_ghost_swarm), candidate_list)
playsound(src, pick(spooky_noises), 100, TRUE)
QDEL_IN(src, 2 MINUTES)
QDEL_IN(WEAKREF(src), 2 MINUTES)
/obj/structure/ghost_portal/process(delta_time)
. = ..()
+1 -1
View File
@@ -219,7 +219,7 @@
pai_card.set_personality(src)
forceMove(pai_card)
card = pai_card
addtimer(VARSET_CALLBACK(src, holochassis_ready, TRUE), HOLOCHASSIS_INIT_TIME)
addtimer(VARSET_WEAK_CALLBACK(src, holochassis_ready, TRUE), HOLOCHASSIS_INIT_TIME)
if(!holoform)
add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), PAI_FOLDED)
desc = "A pAI hard-light holographics emitter. This one appears in the form of a [chassis]."
+3
View File
@@ -107,6 +107,9 @@
summon_objective.summoned = FALSE
summon_objective.killed = TRUE
if (GLOB.cult_narsie == src)
GLOB.cult_narsie = null
return ..()
/obj/narsie/attack_ghost(mob/user)
@@ -157,13 +157,18 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE)
GLOB.running_create_and_destroy = FALSE
//Hell code, we're bound to have ended the round somehow so let's stop if from ending while we work
SSticker.delay_end = TRUE
// Drastically lower the amount of time it takes to GC, since we don't have clients that can hold it up.
SSgarbage.collection_timeout[GC_QUEUE_CHECK] = 10 SECONDS
//Prevent the garbage subsystem from harddeling anything, if only to save time
SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = 10000 HOURS
//Clear it, just in case
cached_contents.Cut()
//Now that we've qdel'd everything, let's sleep until the gc has processed all the shit we care about
var/time_needed = SSgarbage.collection_timeout[GC_QUEUE_CHECK]
// + 2 seconds to ensure that everything gets in the queue.
var/time_needed = SSgarbage.collection_timeout[GC_QUEUE_CHECK] + 2 SECONDS
var/start_time = world.time
var/garbage_queue_processed = FALSE
@@ -215,4 +220,5 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE)
SSticker.delay_end = FALSE
//This shouldn't be needed, but let's be polite
SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = 10 SECONDS
SSgarbage.collection_timeout[GC_QUEUE_CHECK] = GC_CHECK_QUEUE
SSgarbage.collection_timeout[GC_QUEUE_HARDDELETE] = GC_DEL_QUEUE
+1 -1
View File
@@ -223,7 +223,7 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
SSticker.force_ending = TRUE
//We have to call this manually because del_text can preceed us, and SSticker doesn't fire in the post game
SSticker.standard_reboot()
SSticker.declare_completion()
/datum/map_template/unit_tests
name = "Unit Tests Zone"