Fix: Prevent ServerManagerJob executionTime mutation across server loop

Fixed a critical bug where $this->executionTime was being mutated during
the server processing loop, causing incorrect scheduling calculations for
subsequent servers.

The issue occurred at line 123 where subSeconds() was called directly on
the shared executionTime instance. This caused the baseline time to shift
by waitTime seconds with each server iteration, resulting in compounding
scheduling errors (e.g., 1680 seconds drift over 5 servers).

Changed:
- app/Jobs/ServerManagerJob.php:123
  Added .copy() before .subSeconds() to prevent mutation

Added comprehensive unit tests that verify:
- Immutability when using .copy()
- Demonstration of the bug without .copy()
- Correct behavior across multiple iterations

This follows the existing pattern in shouldRunNow() (line 167) and aligns
with other jobs in the codebase.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras BacsaiandClaude committed 2025-12-02 15:27:17 +01:00
1 parent b47181c790
commit ed5796739f
2 files changed
+98 -1

No files matched your search

+1 -1
View File
@@ -120,7 +120,7 @@ class ServerManagerJob implements ShouldQueue
// Check if we should run sentinel-based checks
$lastSentinelUpdate = $server->sentinel_updated_at;
$waitTime = $server->waitBeforeDoingSshCheck();
$sentinelOutOfSync = Carbon::parse($lastSentinelUpdate)->isBefore($this->executionTime->subSeconds($waitTime));
$sentinelOutOfSync = Carbon::parse($lastSentinelUpdate)->isBefore($this->executionTime->copy()->subSeconds($waitTime));
if ($sentinelOutOfSync) {
// Dispatch ServerCheckJob if Sentinel is out of sync