jobId, queueName: $this->queueName, status: 'running', attempts: $this->attempts + 1, maxAttempts: $this->maxAttempts, executionTimeMs: $executionStartTime, memoryUsageBytes: $memoryUsage, errorMessage: $this->errorMessage, createdAt: $this->createdAt, startedAt: date('Y-m-d H:i:s'), completedAt: $this->completedAt, failedAt: $this->failedAt, metadata: $this->metadata ); } public function withCompleted(float $totalExecutionTime, int $peakMemoryUsage): self { return new self( jobId: $this->jobId, queueName: $this->queueName, status: 'completed', attempts: $this->attempts, maxAttempts: $this->maxAttempts, executionTimeMs: $totalExecutionTime, memoryUsageBytes: $peakMemoryUsage, errorMessage: $this->errorMessage, createdAt: $this->createdAt, startedAt: $this->startedAt, completedAt: date('Y-m-d H:i:s'), failedAt: $this->failedAt, metadata: $this->metadata ); } public function withFailed(string $errorMessage, float $executionTime, int $memoryUsage): self { return new self( jobId: $this->jobId, queueName: $this->queueName, status: 'failed', attempts: $this->attempts, maxAttempts: $this->maxAttempts, executionTimeMs: $executionTime, memoryUsageBytes: $memoryUsage, errorMessage: $errorMessage, createdAt: $this->createdAt, startedAt: $this->startedAt, completedAt: $this->completedAt, failedAt: date('Y-m-d H:i:s'), metadata: $this->metadata ); } public function withMetadata(array $metadata): self { return new self( jobId: $this->jobId, queueName: $this->queueName, status: $this->status, attempts: $this->attempts, maxAttempts: $this->maxAttempts, executionTimeMs: $this->executionTimeMs, memoryUsageBytes: $this->memoryUsageBytes, errorMessage: $this->errorMessage, createdAt: $this->createdAt, startedAt: $this->startedAt, completedAt: $this->completedAt, failedAt: $this->failedAt, metadata: array_merge($this->metadata, $metadata) ); } public function getSuccessRate(): Percentage { if ($this->attempts === 0) { return Percentage::from(100.0); } $successfulAttempts = $this->status === 'completed' ? 1 : 0; return Percentage::from(($successfulAttempts / max(1, $this->attempts)) * 100); } public function getExecutionTimeSeconds(): float { return $this->executionTimeMs / 1000.0; } public function getMemoryUsageMB(): float { return $this->memoryUsageBytes / (1024 * 1024); } public function getDuration(): ?int { if (! $this->startedAt) { return null; } $endTime = $this->completedAt ?? $this->failedAt ?? date('Y-m-d H:i:s'); return strtotime($endTime) - strtotime($this->startedAt); } public function isCompleted(): bool { return $this->status === 'completed'; } public function isFailed(): bool { return $this->status === 'failed'; } public function isRunning(): bool { return $this->status === 'running'; } public function isPending(): bool { return $this->status === 'pending'; } public function hasMaxAttempts(): bool { return $this->attempts >= $this->maxAttempts; } public function toArray(): array { return [ 'job_id' => $this->jobId, 'queue_name' => $this->queueName, 'status' => $this->status, 'attempts' => $this->attempts, 'max_attempts' => $this->maxAttempts, 'execution_time_ms' => $this->executionTimeMs, 'execution_time_seconds' => $this->getExecutionTimeSeconds(), 'memory_usage_bytes' => $this->memoryUsageBytes, 'memory_usage_mb' => $this->getMemoryUsageMB(), 'success_rate' => $this->getSuccessRate()->getValue(), 'duration_seconds' => $this->getDuration(), 'error_message' => $this->errorMessage, 'created_at' => $this->createdAt, 'started_at' => $this->startedAt, 'completed_at' => $this->completedAt, 'failed_at' => $this->failedAt, 'metadata' => $this->metadata, ]; } }