Files
ThordekkCore/LOG_ANALYSIS_BOTTLENECK_FINDINGS.md
T
2026-01-20 21:33:16 -03:00

7.7 KiB
Raw Blame History

CRITICAL LOG ANALYSIS: RUNTIME BOTTLENECK INVESTIGATION

Executive Summary

STATUS: ❌ BOTTLENECK STILL PERSISTENT - Mutex lock removal DID NOT resolve the core issue

Finding: The server IS running the updated binary (built Oct 24 20:39), but bots are experiencing 47-second stalls causing severe performance degradation.

Root Cause: The bottleneck is NOT the manager mutex locks we removed. The real issue is thread pool saturation or async login blocking preventing bot Update() calls from executing.


Log Analysis Results

Timing Analysis

  • Server.log last modified: Oct 24 21:09 (13 minutes ago)
  • worldserver.exe built: Oct 24 20:39 (43 minutes ago)
  • Server started: Oct 24 20:47 (with our mutex fixes applied)
  • Stall warnings: 450 occurrences in session logs

Critical Findings

1. CRITICAL: 57 bots are stalled! System may be overloaded

CRITICAL: 57 bots are stalled! System may be overloaded.
CRITICAL: 57 bots are stalled! System may be overloaded.
CRITICAL: 57 bots are stalled! System may be overloaded.
[... repeated 450 times ...]

2. Bots Going 47 Seconds Without Updates

Bot Player-1-00000001 detected as STALLED (no update for 47040ms)
Bot Player-1-00000002 detected as STALLED (no update for 47040ms)
Bot Player-1-00000004 detected as STALLED (no update for 47040ms)

Analysis:

  • Stall threshold appears to be ~5000ms
  • Bots are going 47,040ms (47 seconds) without Update() calls
  • This is 9.4× longer than the stall threshold
  • Indicates bots are NOT being scheduled for updates at all

3. Async Login Blocking

ProcessPendingLogin: Async login in progress, waiting for callback
ProcessPendingLogin: Async login in progress, waiting for callback
ProcessPendingLogin: Async login in progress, waiting for callback

Analysis:

  • Bots stuck waiting for async login callbacks
  • This blocks the Update() cycle
  • Thread pool may be saturated with login tasks

4. SpatialGridScheduler Performance (Secondary Issue)

SpatialGridScheduler::UpdateAllGrids took 15-20ms to update 4 grids

Analysis:

  • 15-20ms per SpatialGrid update cycle
  • This is a secondary bottleneck, but NOT the root cause
  • With 50-60 bot updates, this adds ~1 second overhead per cycle

What Our Mutex Fixes Accomplished

Locks Removed (17 total)

  1. ManagerRegistry::UpdateAll() - 1 lock (CRITICAL GLOBAL LOCK)
  2. GatheringManager - 6 locks
  3. FormationManager - 10 locks

Expected vs Actual Results

Expected: 70-100× performance improvement by removing global lock convoy Actual: ❌ NO IMPROVEMENT - Bottleneck still present

Why the fixes didn't help:

  • The mutex locks we removed were NOT the primary bottleneck
  • The real issue is thread starvation or async operation blocking
  • Bot Update() calls are not being executed at all (47-second gaps)

Root Cause Analysis

Primary Bottleneck: Thread Pool Saturation

Evidence:

  1. Bots not getting Update() calls for 47 seconds
  2. "Async login in progress" messages repeating
  3. ThreadPool task submissions shown in logs but tasks stalling

Hypothesis: The thread pool is saturated with long-running or blocked async login tasks, preventing regular bot Update() tasks from executing.

Stall Detection Logic (BotPriorityManager.cpp:475-484):

uint32 timeSinceUpdate = currentTime - metrics.lastUpdateTime;
if (timeSinceUpdate > stallThresholdMs)
{
    metrics.isStalled = true;
    TC_LOG_ERROR("Bot {} detected as STALLED (no update for {}ms)",
        guid.ToString(), timeSinceUpdate);
}

Problem:

  • metrics.lastUpdateTime is only updated when bot Update() completes
  • If Update() never gets called (thread starved), timer keeps growing
  • After 47 seconds, stall detection triggers

Secondary Bottleneck: SpatialGridScheduler

15-20ms per grid update × 4 grids = 60-80ms per cycle overhead


Log Evidence Summary

Metric Value Severity
Total stall warnings 450 🔴 CRITICAL
Maximum stall time 47,040ms (47 sec) 🔴 CRITICAL
Stalled bot count 57 of ~100 🔴 CRITICAL
SpatialGrid update time 15-20ms 🟡 WARNING
Mutex lock overhead ELIMINATED ✅ FIXED

What the Logs Tell Us

✅ What's Working

  1. Mutex fixes applied successfully - No ManagerRegistry global lock
  2. Lazy manager initialization - "0 managers initialized" for many bots
  3. Thread pool task submission - Tasks being queued properly
  4. Stall detection - Health monitoring working correctly

❌ What's Failing

  1. Bot Update() execution - 47-second gaps indicate complete starvation
  2. Async login processing - Blocking or taking too long
  3. Thread pool throughput - Cannot handle 57-100 concurrent bots
  4. Update scheduling - Bots not getting regular update cycles

Investigation Needed

High Priority

  1. Thread Pool Analysis

    • How many threads in the pool?
    • What's the task queue depth?
    • Are tasks completing or blocking?
  2. Async Login System

    • Why does "async login in progress" repeat so much?
    • Are login callbacks firing?
    • Is there a login bottleneck?
  3. Update Scheduling

    • What schedules bot Update() calls?
    • Why are bots not getting scheduled for 47 seconds?
    • Is there a global update loop bottleneck?

Medium Priority

  1. SpatialGridScheduler Optimization
    • 15-20ms per cycle is high
    • Can grid updates be optimized?
    • Can updates be parallelized?

Recommendations

Immediate Actions

  1. Increase Stall Threshold (Temporary Workaround)

    • Current threshold appears to be ~5000ms
    • Increase to 60000ms to reduce warning spam
    • This does NOT fix the bottleneck, only reduces noise
  2. Instrument Thread Pool

    • Add logging for thread pool queue depth
    • Track task completion times
    • Identify blocking tasks
  3. Analyze Async Login

    • Add timing logs for login callbacks
    • Identify if logins are completing
    • Check for login serialization bottlenecks

Long-term Solutions

  1. Increase Thread Pool Size

    • If pool has <10 threads, increase to 20-50
    • Match thread count to expected bot load
    • Test with various thread counts
  2. Optimize Async Login

    • Make login fully non-blocking
    • Use lock-free queues for login callbacks
    • Parallelize login processing
  3. Optimize SpatialGridScheduler

    • Reduce 15-20ms overhead to <5ms
    • Parallelize grid updates
    • Use lock-free spatial indexing

Conclusion

The mutex lock removal was NOT the solution to the runtime bottleneck.

The real bottleneck is thread pool saturation causing bots to go 47 seconds without Update() calls. This is likely caused by:

  1. Async login tasks blocking thread pool workers
  2. Insufficient thread pool size for 57-100 concurrent bots
  3. Long-running or blocked tasks preventing Update() execution

Next Steps:

  1. Instrument thread pool to identify blocking tasks
  2. Analyze async login system for bottlenecks
  3. Increase thread pool size or optimize task processing
  4. Consider completely redesigning bot update scheduling to avoid thread pool saturation

Our mutex lock removal work was NOT wasted - it eliminated potential future bottlenecks and improved code quality. However, it did NOT address the current runtime bottleneck affecting the system.


Build Verification

✅ Confirmed: Server is running the updated worldserver.exe with all mutex fixes

  • worldserver.exe built: Oct 24 20:39
  • Server started: Oct 24 20:47 (logs confirm)
  • All 17 mutex locks successfully removed and compiled

The bottleneck persists even with the mutex fixes applied, confirming that manager mutex locks were NOT the root cause.