perf(mmap): Cache failed MMAP load attempts to prevent repeated retries
Similar to the VMAP fix, this caches failed MMAP load attempts using a bitset per TerrainInfo instance. This prevents the server from repeatedly attempting to load MMAP tiles that don't exist (e.g., unused dungeon maps, boost experience maps, etc.), which was causing significant slowdowns. Changes: - Add _mmapLoadFailed bitset to TerrainInfo class - Skip LoadMMapImpl early if grid already marked as failed - Cache FileNotFound, VersionMismatch, ReadFromFileFailed, and LibraryError results - Change expected "FileNotFound" log level from WARN to DEBUG - Update analysis documentation with fix status Impact: Near-instant returns for grids with missing MMAP data instead of repeated file I/O attempts. Co-Authored-By: Claude Opus 4.5 <[email protected]> Signed-off-by: luis <[email protected]>
This commit is contained in:
committed by
luis
co-authored by
Claude Opus 4.5
parent
cfe60008d5
commit
c986da9c77
@@ -353,13 +353,36 @@ When 100 bots enter a map simultaneously, ALL 100 queue on exclusive lock.
|
||||
| GameSystemsManager Throttling | HIGH | ✅ FIXED | ~30x fewer manager updates |
|
||||
| SpatialGridManager Thundering Herd | MEDIUM | ✅ FIXED | Instant returns for existing grids |
|
||||
| Main Thread ThreadPool Blocking | HIGH | ⚠️ MITIGATED | Fixed by making workers faster |
|
||||
| CombatEventRouter | MEDIUM | ⏳ ACCEPTABLE | Already uses good patterns |
|
||||
| CombatEventRouter | MEDIUM | ✅ FIXED | Lock-free stats with atomics |
|
||||
| VMAP Repeated Load Attempts | HIGH | ✅ FIXED | Cache failed loads, no retries |
|
||||
| MMAP Repeated Load Attempts | HIGH | ✅ FIXED | Cache failed loads, no retries |
|
||||
| Unordered Mutexes | LOW | ⏳ DEFERRED | For future cleanup |
|
||||
|
||||
**Total Build Status:** ✅ worldserver.exe compiled successfully
|
||||
|
||||
---
|
||||
|
||||
## VMAP/MMAP LOAD CACHING FIX
|
||||
|
||||
### Problem
|
||||
When maps reference VMAP/MMAP tiles that don't exist in client data (e.g., "8.0 Boost Experience",
|
||||
TWW dungeons), the server repeatedly attempts to load them on every grid access, causing:
|
||||
- Repeated file I/O operations
|
||||
- Log spam with warnings
|
||||
- Significant server slowdown
|
||||
|
||||
### Solution
|
||||
Added `_vmapLoadFailed` and `_mmapLoadFailed` bitset caches to `TerrainInfo` class:
|
||||
- On first load failure, mark the grid as failed
|
||||
- Skip subsequent load attempts for the same grid
|
||||
- Changed log level from WARN to DEBUG for expected failures
|
||||
|
||||
**File:** `src/server/game/Maps/TerrainMgr.h` and `TerrainMgr.cpp`
|
||||
|
||||
**Expected Impact:** Near-instant returns for grids with missing map data
|
||||
|
||||
---
|
||||
|
||||
## THREADING CONFIGURATION
|
||||
|
||||
### TrinityCore MapUpdate.Threads
|
||||
|
||||
@@ -252,6 +252,10 @@ void TerrainInfo::LoadMMapImpl(uint32 instanceId, int32 gx, int32 gy)
|
||||
if (!DisableMgr::IsPathfindingEnabled(GetId()))
|
||||
return;
|
||||
|
||||
// PLAYERBOT FIX: Skip loading if we already know this tile failed (prevents repeated file access attempts)
|
||||
if (_mmapLoadFailed[GetBitsetIndex(gx, gy)])
|
||||
return;
|
||||
|
||||
switch (MMAP::LoadResult mmapLoadResult = MMAP::MMapManager::instance()->loadMap(sWorld->GetDataPath(), GetId(), instanceId, gx, gy))
|
||||
{
|
||||
case MMAP::LoadResult::Success:
|
||||
@@ -260,9 +264,19 @@ void TerrainInfo::LoadMMapImpl(uint32 instanceId, int32 gx, int32 gy)
|
||||
case MMAP::LoadResult::AlreadyLoaded:
|
||||
break;
|
||||
case MMAP::LoadResult::FileNotFound:
|
||||
// PLAYERBOT FIX: Cache the failure to prevent repeated load attempts
|
||||
_mmapLoadFailed[GetBitsetIndex(gx, gy)] = true;
|
||||
if (_parentTerrain)
|
||||
break; // don't log tile not found errors for child maps
|
||||
[[fallthrough]];
|
||||
TC_LOG_DEBUG("mmaps.tiles", "MMAP not available name:{}, id:{}, x:{}, y:{} (mmap rep.: x:{}, y:{}) - will not retry", GetMapName(), GetId(), gx, gy, gx, gy);
|
||||
break;
|
||||
case MMAP::LoadResult::VersionMismatch:
|
||||
case MMAP::LoadResult::ReadFromFileFailed:
|
||||
case MMAP::LoadResult::LibraryError:
|
||||
// PLAYERBOT FIX: Cache these failures too - they won't succeed on retry
|
||||
_mmapLoadFailed[GetBitsetIndex(gx, gy)] = true;
|
||||
TC_LOG_WARN("mmaps.tiles", "MMAP failed name:{}, id:{}, x:{}, y:{} (mmap rep.: x:{}, y:{}) result: {} - will not retry", GetMapName(), GetId(), gx, gy, gx, gy, AsUnderlyingType(mmapLoadResult));
|
||||
break;
|
||||
default:
|
||||
TC_LOG_WARN("mmaps.tiles", "Could not load MMAP name:{}, id:{}, x:{}, y:{} (mmap rep.: x:{}, y:{}) result: {}", GetMapName(), GetId(), gx, gy, gx, gy, AsUnderlyingType(mmapLoadResult));
|
||||
break;
|
||||
|
||||
@@ -116,6 +116,7 @@ private:
|
||||
std::array<uint64, MAX_NUMBER_OF_GRIDS> _loadedGrids;
|
||||
std::bitset<MAX_NUMBER_OF_GRIDS * MAX_NUMBER_OF_GRIDS> _gridFileExists; // cache what grids are available for this map (not including parent/child maps)
|
||||
std::bitset<MAX_NUMBER_OF_GRIDS * MAX_NUMBER_OF_GRIDS> _vmapLoadFailed; // PLAYERBOT FIX: cache failed VMAP loads to prevent repeated attempts
|
||||
std::bitset<MAX_NUMBER_OF_GRIDS * MAX_NUMBER_OF_GRIDS> _mmapLoadFailed; // PLAYERBOT FIX: cache failed MMAP loads to prevent repeated attempts
|
||||
|
||||
static constexpr Milliseconds CleanupInterval = 1min;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user