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.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -4,11 +4,11 @@ declare(strict_types=1);
namespace App\Framework\Queue\Services;
use App\Framework\Queue\Contracts\JobDependencyManagerInterface;
use App\Framework\Logging\Logger;
use App\Framework\Queue\Contracts\JobChainManagerInterface;
use App\Framework\Queue\Contracts\JobDependencyManagerInterface;
use App\Framework\Queue\Contracts\QueueInterface;
use App\Framework\Queue\ValueObjects\Job;
use App\Framework\Logging\Logger;
final readonly class DependencyResolutionEngine
{
@@ -17,7 +17,8 @@ final readonly class DependencyResolutionEngine
private JobChainManagerInterface $chainManager,
private QueueInterface $queue,
private Logger $logger
) {}
) {
}
/**
* Process job completion and resolve any dependent jobs that can now be executed
@@ -26,7 +27,7 @@ final readonly class DependencyResolutionEngine
{
$this->logger->info('Starting dependency resolution for completed job', [
'job_id' => $jobId,
'successful' => $successful
'successful' => $successful,
]);
$resolvedJobs = [];
@@ -38,7 +39,7 @@ final readonly class DependencyResolutionEngine
$resolvedJobs[] = [
'job_id' => $dependentJobId,
'type' => 'dependency_resolved',
'trigger_job' => $jobId
'trigger_job' => $jobId,
];
}
@@ -59,13 +60,13 @@ final readonly class DependencyResolutionEngine
'job_id' => $nextJobId,
'type' => 'chain_progression',
'chain_id' => $chainEntry->chainId,
'trigger_job' => $jobId
'trigger_job' => $jobId,
];
} else {
$this->logger->info('Next job in chain has unsatisfied dependencies', [
'chain_id' => $chainEntry->chainId,
'next_job_id' => $nextJobId,
'unsatisfied_deps' => count($this->dependencyManager->getUnsatisfiedDependencies($nextJobId))
'unsatisfied_deps' => count($this->dependencyManager->getUnsatisfiedDependencies($nextJobId)),
]);
}
}
@@ -75,7 +76,7 @@ final readonly class DependencyResolutionEngine
$this->logger->info('Dependency resolution completed', [
'trigger_job_id' => $jobId,
'resolved_jobs_count' => count($resolvedJobs),
'resolved_jobs' => array_column($resolvedJobs, 'job_id')
'resolved_jobs' => array_column($resolvedJobs, 'job_id'),
]);
return $resolvedJobs;
@@ -90,7 +91,7 @@ final readonly class DependencyResolutionEngine
$this->logger->debug('Found jobs ready for execution', [
'ready_jobs_count' => count($readyJobs),
'ready_jobs' => $readyJobs
'ready_jobs' => $readyJobs,
]);
return $readyJobs;
@@ -113,17 +114,17 @@ final readonly class DependencyResolutionEngine
'job_id' => $jobId,
'valid' => false,
'error' => 'circular_dependency',
'dependency_chain' => $dependencyChain
'dependency_chain' => $dependencyChain,
];
$this->logger->warning('Circular dependency detected', [
'job_id' => $jobId,
'dependency_chain' => $dependencyChain
'dependency_chain' => $dependencyChain,
]);
} else {
$validationResults[] = [
'job_id' => $jobId,
'valid' => true
'valid' => true,
];
}
}
@@ -145,21 +146,21 @@ final readonly class DependencyResolutionEngine
return [
'job_id' => $jobId,
'can_execute' => $canExecute,
'direct_dependencies' => array_map(fn($dep) => [
'direct_dependencies' => array_map(fn ($dep) => [
'depends_on_job_id' => $dep->dependsOnJobId,
'dependency_type' => $dep->dependencyType,
'is_satisfied' => $dep->isSatisfied,
'condition' => $dep->conditionExpression
'condition' => $dep->conditionExpression,
], $dependencies),
'dependent_jobs' => array_map(fn($dep) => [
'dependent_jobs' => array_map(fn ($dep) => [
'dependent_job_id' => $dep->dependentJobId,
'dependency_type' => $dep->dependencyType,
'is_satisfied' => $dep->isSatisfied
'is_satisfied' => $dep->isSatisfied,
], $dependents),
'unsatisfied_dependencies' => array_map(fn($dep) => [
'unsatisfied_dependencies' => array_map(fn ($dep) => [
'depends_on_job_id' => $dep->dependsOnJobId,
'dependency_type' => $dep->dependencyType,
'condition' => $dep->conditionExpression
'condition' => $dep->conditionExpression,
], $unsatisfiedDeps),
'full_dependency_chain' => $dependencyChain,
'statistics' => [
@@ -167,8 +168,8 @@ final readonly class DependencyResolutionEngine
'satisfied_dependencies' => count($dependencies) - count($unsatisfiedDeps),
'unsatisfied_dependencies' => count($unsatisfiedDeps),
'total_dependents' => count($dependents),
'chain_depth' => count($dependencyChain)
]
'chain_depth' => count($dependencyChain),
],
];
}
@@ -193,14 +194,14 @@ final readonly class DependencyResolutionEngine
'progress' => $progress,
'next_job_after_current' => $nextJob,
'job_position' => $this->getJobPositionInChain($jobId, $chainEntry),
'total_jobs' => count($chainEntry->getJobIdsArray())
'total_jobs' => count($chainEntry->getJobIdsArray()),
];
}
return [
'job_id' => $jobId,
'chains' => $chainAnalysis,
'total_chains' => count($chains)
'total_chains' => count($chains),
];
}
@@ -228,7 +229,7 @@ final readonly class DependencyResolutionEngine
$issues[] = [
'type' => 'stalled_chain',
'chain_id' => $chain->chainId,
'hours_running' => round($hoursRunning, 2)
'hours_running' => round($hoursRunning, 2),
];
}
}
@@ -241,7 +242,7 @@ final readonly class DependencyResolutionEngine
$issues[] = [
'type' => 'many_unsatisfied_dependencies',
'job_id' => $jobId,
'unsatisfied_count' => $analysis['statistics']['unsatisfied_dependencies']
'unsatisfied_count' => $analysis['statistics']['unsatisfied_dependencies'],
];
}
}
@@ -253,14 +254,14 @@ final readonly class DependencyResolutionEngine
'active_chains' => count($activeChains),
'pending_chains' => count($pendingChains),
'ready_jobs' => count($readyJobs),
'detected_issues' => count($issues)
'detected_issues' => count($issues),
],
'issues' => $issues
'issues' => $issues,
];
$this->logger->info('Dependency system health check completed', [
'status' => $healthReport['status'],
'issues_count' => count($issues)
'issues_count' => count($issues),
]);
return $healthReport;
@@ -269,6 +270,7 @@ final readonly class DependencyResolutionEngine
private function getJobPositionInChain(string $jobId, object $chainEntry): ?int
{
$jobIds = $chainEntry->getJobIdsArray();
return array_search($jobId, $jobIds, true) ?: null;
}
}
}