Closed kdomanski closed 3 months ago
The delay is the result of spawning git
subprocesses during initialization. Moonraker checks the git config for each repo to see if any other instances of Moonraker are managing the same repo, then adds its own instance ID to the git config. The goal is to warn if multiple instances of Moonraker are managing the same repo, as this is not desirable.
I have some concerns about spawning concurrent git processes. Historically I have found git to be finicky, so I have intentionally avoided re-entry with regard to init and refresh.
Hey, thanks for the explanation. Care to elaborate about the troubles you've encountered? TBH I don't see any additional re-entrant execution here, since the spawning is per GitDeploy instance. Whatever race condition this might create, already exist due to refresh timers, no?
Your response triggered another idea though. I changed the UpdateManager.component_init()
method to run lazily (with event_loop.register_callback
) and it shaved off almost another second (now 6.6s -> 2.2s). I'd argue that it's a good idea to already start the server while the update manager is still doing its initial checks in the background. On my printer, this represents about 15% of total startup time.
If you're open to more back-and-forth about this, we can take the conversation to Discord.
I looked at this in a bit more detail and decided to make a change in commit 10dfb0d47729d4c8af3df30d9fd020c7b5e1ee0c. Rather than use the git config to store multi-instance info the update manager will use shared memory. This only occurs once for the entire UM, which avoids the slowdown introduced by calling git config
.
FWIW, it is necessary to run the UM's component_init()
prior to the server starting. Several attributes are set in initialize()
, lazily setting them would potentially result in an exception if a frontend requests the status
endpoint before they are set.
I looked at this in a bit more detail and decided to make a change in commit 10dfb0d. Rather than use the git config to store multi-instance info the update manager will use shared memory. This only occurs once for the entire UM, which avoids the slowdown introduced by calling
git config
.
I just measured, this is fantastic! Speedup from 6.6s to 2.3s. Thank you for being so open to tackling this!
FWIW, it is necessary to run the UM's
component_init()
prior to the server starting. Several attributes are set ininitialize()
, lazily setting them would potentially result in an exception if a frontend requests thestatus
endpoint before they are set.
In my test with lazy init, it was sufficient to add self.last_refresh_time = 0.0
in the constructor. But hey, with your new changes it doesn't matter anymore.
Massively speeds up startup on setups with many git repos.
I cannot figure out what takes so long to
initialize()
theGitDeploy
instances and thepyinstrument
lib doesn't work well with asyncio.The fact is, running all initializers at once instead of waiting for one at a time speeds up my
server_init()
from ~6.5 seconds to ~3 seconds.Relevant slice of my
moonraker.conf
: