$job]) ); } public static function immediate(object $job): self { return self::create( job: $job, priority: QueuePriority::high(), delay: Duration::zero() ); } public static function delayed(object $job, Duration $delay): self { return self::create( job: $job, delay: $delay ); } public static function critical(object $job): self { return self::create( job: $job, priority: QueuePriority::critical(), delay: Duration::zero(), timeout: Duration::fromSeconds(30) ); } public static function background(object $job): self { return self::create( job: $job, priority: QueuePriority::low(), timeout: Duration::fromMinutes(30), retryStrategy: new ExponentialBackoffStrategy(maxAttempts: 5) ); } public function withPriority(QueuePriority $priority): self { return new self( job: $this->job, priority: $priority, delay: $this->delay, timeout: $this->timeout, retryStrategy: $this->retryStrategy, metadata: $this->metadata ); } public function withDelay(Duration $delay): self { return new self( job: $this->job, priority: $this->priority, delay: $delay, timeout: $this->timeout, retryStrategy: $this->retryStrategy, metadata: $this->metadata ); } public function withTimeout(Duration $timeout): self { return new self( job: $this->job, priority: $this->priority, delay: $this->delay, timeout: $timeout, retryStrategy: $this->retryStrategy, metadata: $this->metadata ); } public function withRetryStrategy(RetryStrategy $strategy): self { return new self( job: $this->job, priority: $this->priority, delay: $this->delay, timeout: $this->timeout, retryStrategy: $strategy, metadata: $this->metadata ); } public function withMetadata(JobMetadata $metadata): self { return new self( job: $this->job, priority: $this->priority, delay: $this->delay, timeout: $this->timeout, retryStrategy: $this->retryStrategy, metadata: $metadata ); } public function isReady(): bool { return $this->delay->toSeconds() === 0; } public function isDelayed(): bool { return $this->delay->toSeconds() > 0; } public function hasRetryStrategy(): bool { return $this->retryStrategy !== null; } public function hasTimeout(): bool { return $this->timeout !== null; } /** * Calculate available time (when the job can be processed) */ public function getAvailableTime(): int { if ($this->delay->toSeconds() === 0) { return time(); } return time() + (int) $this->delay->toSeconds(); } /** * Serialize for storage */ public function serialize(): string { return serialize($this->job); } /** * Get job class name */ public function getJobClass(): string { return get_class($this->job); } public function toArray(): array { return [ 'job_class' => $this->getJobClass(), 'priority' => $this->priority->toString(), 'priority_value' => $this->priority->value, 'delay_seconds' => $this->delay->toSeconds(), 'timeout_seconds' => $this->timeout?->toSeconds(), 'has_retry_strategy' => $this->hasRetryStrategy(), 'max_attempts' => $this->retryStrategy?->getMaxAttempts(), 'available_at' => $this->getAvailableTime(), 'metadata' => $this->metadata?->toArray(), ]; } }