Files
michaelschiemer/src/Framework/Queue/ValueObjects/JobChain.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

167 lines
4.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Queue\ValueObjects;
/**
* Value Object representing a chain of jobs with their execution order
*/
final readonly class JobChain
{
/** @var string[] */
public array $jobIds;
public function __construct(
public string $chainId,
public string $name,
array $jobIds,
public ChainExecutionMode $executionMode = ChainExecutionMode::SEQUENTIAL,
public bool $stopOnFailure = true,
public ?array $metadata = null
) {
$this->jobIds = array_values(array_unique($jobIds));
$this->validate();
}
public static function sequential(string $chainId, string $name, array $jobIds): self
{
return new self($chainId, $name, $jobIds, ChainExecutionMode::SEQUENTIAL);
}
public static function parallel(string $chainId, string $name, array $jobIds): self
{
return new self($chainId, $name, $jobIds, ChainExecutionMode::PARALLEL);
}
public static function conditional(string $chainId, string $name, array $jobIds): self
{
return new self($chainId, $name, $jobIds, ChainExecutionMode::CONDITIONAL);
}
public function isSequential(): bool
{
return $this->executionMode === ChainExecutionMode::SEQUENTIAL;
}
public function isParallel(): bool
{
return $this->executionMode === ChainExecutionMode::PARALLEL;
}
public function isConditional(): bool
{
return $this->executionMode === ChainExecutionMode::CONDITIONAL;
}
public function shouldStopOnFailure(): bool
{
return $this->stopOnFailure;
}
public function getJobCount(): int
{
return count($this->jobIds);
}
public function getFirstJob(): ?string
{
return $this->jobIds[0] ?? null;
}
public function getLastJob(): ?string
{
return end($this->jobIds) ?: null;
}
public function containsJob(string $jobId): bool
{
return in_array($jobId, $this->jobIds, true);
}
public function getJobPosition(string $jobId): ?int
{
$position = array_search($jobId, $this->jobIds, true);
return $position !== false ? $position : null;
}
public function getNextJob(string $currentJobId): ?string
{
$position = $this->getJobPosition($currentJobId);
if ($position === null) {
return null;
}
return $this->jobIds[$position + 1] ?? null;
}
public function getPreviousJob(string $currentJobId): ?string
{
$position = $this->getJobPosition($currentJobId);
if ($position === null || $position === 0) {
return null;
}
return $this->jobIds[$position - 1];
}
public function withMetadata(array $metadata): self
{
return new self(
chainId: $this->chainId,
name: $this->name,
jobIds: $this->jobIds,
executionMode: $this->executionMode,
stopOnFailure: $this->stopOnFailure,
metadata: array_merge($this->metadata ?? [], $metadata)
);
}
public function withStopOnFailure(bool $stopOnFailure): self
{
return new self(
chainId: $this->chainId,
name: $this->name,
jobIds: $this->jobIds,
executionMode: $this->executionMode,
stopOnFailure: $stopOnFailure,
metadata: $this->metadata
);
}
public function toArray(): array
{
return [
'chain_id' => $this->chainId,
'name' => $this->name,
'job_ids' => $this->jobIds,
'execution_mode' => $this->executionMode->value,
'stop_on_failure' => $this->stopOnFailure,
'job_count' => $this->getJobCount(),
'metadata' => $this->metadata,
];
}
private function validate(): void
{
if (empty(trim($this->chainId))) {
throw new \InvalidArgumentException('Chain ID cannot be empty');
}
if (empty(trim($this->name))) {
throw new \InvalidArgumentException('Chain name cannot be empty');
}
if (empty($this->jobIds)) {
throw new \InvalidArgumentException('Job chain must contain at least one job');
}
foreach ($this->jobIds as $jobId) {
if (empty(trim($jobId))) {
throw new \InvalidArgumentException('Job ID cannot be empty');
}
}
}
}