perf(init): skip redundant database compilation

This commit is contained in:
Aron
2026-07-05 16:26:12 +02:00
parent 558aeb3888
commit 1f3d5fbb61
3 changed files with 72 additions and 6 deletions
+5
View File
@@ -9,6 +9,8 @@ local QuestieDB = QuestieLoader:ImportModule("QuestieDB")
local QuestieLib = QuestieLoader:ImportModule("QuestieLib")
---@type l10n
local l10n = QuestieLoader:ImportModule("l10n")
---@type QuestiePluginAPI
local QuestiePluginAPI = QuestieLoader:ImportModule("QuestiePluginAPI")
--- COMPATIBILITY ---
local WOW_PROJECT_ID = QuestieCompat.WOW_PROJECT_ID
@@ -1095,6 +1097,7 @@ function QuestieDBCompiler:Compile()
print("\124cFFAAEEFF"..l10n("Questie DB update complete!"))
Questie.db.global.dbCompiledExpansion = WOW_PROJECT_ID
Questie.db.global.dbCompiledPluginSignature = QuestiePluginAPI:GetLoadedSignature()
if Questie.IsSoD then
Questie.db.global.sod.dbCompiledOnVersion = QuestieLib:GetAddonVersionString()
@@ -1107,6 +1110,8 @@ function QuestieDBCompiler:Compile()
Questie.db.global.dbIsCompiled = true
Questie.db.global.dbCompiledCount = (Questie.db.global.dbCompiledCount or 0) + 1
end
QuestieDBCompiler._isCompiling = false
end
function QuestieDBCompiler:ValidateNPCs()
+47
View File
@@ -4,6 +4,28 @@ local QuestiePluginAPI = QuestieLoader:CreateModule("QuestiePluginAPI")
QuestiePluginAPI.registeredPlugins = {}
QuestiePluginAPI.loadedDBFlavor = nil -- set by the first DB plugin that calls FinishLoading
QuestiePluginAPI.pendingPluginsCount = 0 -- count of plugins that have registered but not yet FinishedLoading
QuestiePluginAPI.loadedDBVersions = {}
local KNOWN_PLUGIN_ADDONS = {
WotLKDB = "Questie-X-WotLKDB",
ClassicDB = "Questie-X-ClassicDB",
TBCDB = "Questie-X-TBCDB",
Ascension = "Questie-X-AscensionDB",
AscensionDB = "Questie-X-AscensionDB",
Ebonhold = "Questie-X-EbonholdDB",
EbonholdDB = "Questie-X-EbonholdDB",
Valanior = "Questie-X-ValaniorDB",
ValaniorDB = "Questie-X-ValaniorDB",
RetailDB = "Questie-X-RetailDB",
}
local function GetPluginAddonVersion(pluginName, flavorKey)
local addonName = KNOWN_PLUGIN_ADDONS[flavorKey] or KNOWN_PLUGIN_ADDONS[pluginName] or pluginName
if GetAddOnMetadata then
return GetAddOnMetadata(addonName, "Version") or "unknown"
end
return "unknown"
end
--- Returns true if at least one DB plugin has fully loaded.
---@return boolean
@@ -27,6 +49,27 @@ function QuestiePluginAPI:GetLoadedFlavor()
return self.loadedDBFlavor
end
--- Returns a stable signature for loaded DB plugin data.
---@return string
function QuestiePluginAPI:GetLoadedSignature()
local parts = {}
local pluginName, plugin = next(self.registeredPlugins)
while pluginName do
local version = self.loadedDBVersions[pluginName] or plugin.version or "pending"
local flavor = plugin.flavorKey or pluginName
local stats = plugin.stats or {}
parts[#parts + 1] = pluginName .. ":" .. flavor .. ":" .. version
.. ":Q" .. tostring(stats.QUEST or 0)
.. ":N" .. tostring(stats.NPC or 0)
.. ":O" .. tostring(stats.OBJECT or 0)
.. ":I" .. tostring(stats.ITEM or 0)
pluginName, plugin = next(self.registeredPlugins, pluginName)
end
table.sort(parts)
return table.concat(parts, "|")
end
---@class QuestiePlugin
local QuestiePlugin = {}
QuestiePlugin.__index = QuestiePlugin
@@ -298,6 +341,10 @@ function QuestiePlugin:FinishLoading(flavorKey)
QuestiePluginAPI.loadedDBFlavor = self.name
end
self.flavorKey = flavorKey or self.name
self.version = GetPluginAddonVersion(self.name, self.flavorKey)
QuestiePluginAPI.loadedDBVersions[self.name] = self.version
if not self.isFinished then
self.isFinished = true
QuestiePluginAPI.pendingPluginsCount = math.max(0, QuestiePluginAPI.pendingPluginsCount - 1)
+20 -6
View File
@@ -383,9 +383,13 @@ QuestieInit.Stages[3] = function() -- run as a coroutine
local waitStart = GetTime()
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieInit:Stage3] Waiting for plugins to register/finish. Initial pending: " .. QuestiePluginAPI.pendingPluginsCount)
-- Give other addons/scripts a moment to fire and register if they were waiting for PLAYER_LOGIN
while (GetTime() - waitStart < 1.0) do
coYield()
-- Give DB plugins a short grace period only when a plugin addon is enabled
-- but none has registered yet. Avoid adding a fixed one-second delay to
-- every login after plugins are already registered.
if QuestieServer:IsAnyDBPluginEnabled() and (not QuestiePluginAPI:IsAnyPluginLoaded()) then
while (GetTime() - waitStart < 1.0) do
coYield()
end
end
local timeout = 10
@@ -395,16 +399,26 @@ QuestieInit.Stages[3] = function() -- run as a coroutine
elapsed = GetTime() - waitStart
end
-- Always re-compile on custom servers to pick up QuestieLearner changes from SavedVariables,
-- or if compilation was explicitly deferred/needed.
-- Recompile custom-server/plugin data only when the compiled cache no longer
-- matches the loaded plugin set. Learner data is applied as live overrides and
-- does not require rebuilding the binary DB cache on every login.
local isCustomServer = Questie.IsAscension or Questie.IsEbonhold or Questie.IsValanior or QuestieServer:IsAnyDBPluginEnabled()
if isCustomServer or needsCompilation or (not Questie.db.global.dbIsCompiled) then
local pluginSignature = QuestiePluginAPI:GetLoadedSignature()
local cacheMatchesPlugins = Questie.db.global.dbCompiledPluginSignature == pluginSignature
local cacheMatchesCore = Questie.db.global.dbIsCompiled
and (QuestieLib:GetAddonVersionString() == Questie.db.global.dbCompiledOnVersion)
and (l10n:GetUILocale() == Questie.db.global.dbCompiledLang)
and (Questie.db.global.dbCompiledExpansion == WOW_PROJECT_ID)
if needsCompilation or (not cacheMatchesCore) or (isCustomServer and (not cacheMatchesPlugins)) then
Questie:Debug(Questie.DEBUG_CRITICAL, "[QuestieInit:Stage3] Starting compilation (Server=" .. tostring(isCustomServer) .. ", Needed=" .. tostring(needsCompilation) .. ")")
if not QuestieDB.questData then
loadFullDatabase()
end
QuestieDBCompiler:Compile()
QuestieDB:Initialize()
else
Questie:Debug(Questie.DEBUG_INFO, "[QuestieInit:Stage3] DB cache is current; skipping compilation.")
end
-- register events that rely on questie being initialized