-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Old PQS coroutines are never stopped, causing perf degradation over time #85
Comments
So, this is quite difficult to fix, but with some messing around it's at least possible to avoid all Main fix involves changing the However, simply fixing the stock bug isn't enough because the stock PQS lifecycle isn't designed at all to ensure only one coroutine exists at a given time. Notably (but not limited to), it seems there is no guaranteed code path at all that could clean up the old coroutines when the PQS is restarted while it was already the active PQS. This notably mean that on scene switches, if the main body doesn't change, a new coroutine is created without stopping the old one. Trying to aggressively kill the coroutines (either from within the coroutine, or externally) when a PQS is not the main body anymore occasionally result in killing the actually needed coroutine. Such solutions seems too risky, there are too many corner cases and delays / order shenanigans in the PQS execution flow. A poor man alternative is to always call |
- New performance / KSP bugfix patch : [PQSCoroutineLeak](#85) (issue discovered by @Gameslinx) - Fixed the ToolbarShowHide patch partially failing due to an ambigious match exception when searching the no args `ApplicationLauncher.ShouldItHide()` method overload.
Hmm, could you inject code into the coroutine itself that detects when it's not needed anymore and ends it? |
That's what I meant with "Trying to aggressively kill the coroutines (either from within the coroutine, or externally) when a PQS is not the main body anymore occasionally result in killing the actually needed coroutine." I haven't found a reliable way to "detect when it's not needed anymore". If I try to self-kill them when the PQS isn't supposed to be active anymore, there are a bunch of corner cases where if the PQS is reactivated latter, it doesn't go through a code path spawning a new coroutine. I don't remember everything I tried, but trying to self-kill the coroutine also face the issue that the coroutine is spawned before the PQS stuff is fully initialized, so you can also end up self-killing the newly spawned coroutine. Everything I tried didn't work consistently so I gave up because without investigating too long, I have a feeling this would be a pretty deep rabbit hole. In fact, I think that the main bug causing those coroutines to never be stopped has been around since forever without any functional side effect (although there are definitely occasional "PQS crash, restarting" entries popping up in the logs), so this was hiding the fact that there is a hole in the PQS lifecycle management . Maybe it's possible to patch that hole but I'm not willing to put my hands in this mess. The committed patch takes care of the "leak" with minimal intervention, it solves the main problem of unrecoverable perf degradation over time. With the patch, worst case scenario (visiting multiple SOIs without a scene switch or reload in between) you have an extra update function consuming ~0.3 ms lying around. And this is not systematic, I'm not even sure it's reproducible without aggressively teleporting from one SOI to another like I was doing for testing. |
This has shipped. |
- New performance / KSP bugfix patch : [PQSCoroutineLeak](#85) (issue discovered by @Gameslinx) - Fixed the ToolbarShowHide patch partially failing due to an ambigious match exception when searching the no args `ApplicationLauncher.ShouldItHide()` method overload.
Quoting @Gameslinx :
Likely cause :
PQS.ResetSphere()
is callingStopCoroutine("UpdateSphere")
.This is the overload that takes a string arg for a named coroutine, but that only work if the coroutine was started using the matching string overload, which isn't the case, the coroutine is started in
PQS.StartSphere()
with theIEnumerator
arg overload :StartCoroutine(UpdateSphere())
The text was updated successfully, but these errors were encountered: