chainManager->createChain($jobChain); echo "โœ… Job chain created: {$name} ({$chainId})\n"; echo " Jobs: " . implode(' โ†’ ', $jobIdArray) . "\n"; echo " Mode: {$executionMode}\n"; echo " Stop on failure: " . ($stopOnFailure ? 'Yes' : 'No') . "\n"; } #[ConsoleCommand(name: 'queue:chain:start', description: 'Start execution of a job chain')] public function startChain(string $chainId): void { try { $this->coordinator->startChainExecution($chainId); echo "๐Ÿš€ Chain execution started: {$chainId}\n"; } catch (\Exception $e) { echo "โŒ Failed to start chain: {$e->getMessage()}\n"; } } #[ConsoleCommand(name: 'queue:chain:status', description: 'Get status of a job chain')] public function getChainStatus(string $chainId): void { try { $status = $this->coordinator->getChainExecutionStatus($chainId); echo "๐Ÿ“‹ Chain Status: {$status['name']} ({$chainId})\n\n"; $statusIcon = match($status['status']) { 'pending' => 'โณ', 'running' => '๐Ÿ”„', 'completed' => 'โœ…', 'failed' => 'โŒ', default => 'โ“' }; echo " Status: {$statusIcon} {$status['status']}\n"; echo " Execution Mode: {$status['execution_mode']}\n"; echo " Stop on Failure: " . ($status['progress']['stop_on_failure'] ? 'Yes' : 'No') . "\n"; if ($status['started_at']) { echo " Started: {$status['started_at']}\n"; } if ($status['completed_at']) { echo " Completed: {$status['completed_at']}\n"; } echo "\n๐Ÿ“Š Progress:\n"; echo " {$status['progress']['completed_jobs']}/{$status['progress']['total_jobs']} jobs completed ({$status['progress']['percentage']}%)\n\n"; echo "๐Ÿ”— Job Status:\n"; foreach ($status['job_statuses'] as $jobStatus) { $canExecute = $jobStatus['can_execute'] ? 'โœ…' : 'โณ'; $depStatus = "{$jobStatus['dependencies_satisfied']}/{$jobStatus['dependencies_total']} deps"; $position = $jobStatus['position'] + 1; echo " {$canExecute} Job {$position}: {$jobStatus['job_id']} ({$depStatus})\n"; } } catch (\Exception $e) { echo "โŒ Failed to get chain status: {$e->getMessage()}\n"; } } #[ConsoleCommand(name: 'queue:chain:list', description: 'List job chains by status')] public function listChains(string $status = 'all'): void { $chains = match($status) { 'active' => $this->chainManager->getActiveChains(), 'pending' => $this->chainManager->getPendingChains(), default => array_merge( $this->chainManager->getPendingChains(), $this->chainManager->getActiveChains() ) }; echo "๐Ÿ“‹ Job Chains ({$status}):\n\n"; if (empty($chains)) { echo " No chains found\n"; return; } foreach ($chains as $chain) { $statusIcon = match($chain->status) { 'pending' => 'โณ', 'running' => '๐Ÿ”„', 'completed' => 'โœ…', 'failed' => 'โŒ', default => 'โ“' }; $jobCount = count($chain->getJobIdsArray()); echo " {$statusIcon} {$chain->name} ({$chain->chainId})\n"; echo " Status: {$chain->status} | Jobs: {$jobCount} | Mode: {$chain->executionMode}\n"; if ($chain->startedAt) { echo " Started: {$chain->startedAt}\n"; } echo "\n"; } } #[ConsoleCommand(name: 'queue:chain:analyze', description: 'Analyze job chains for a specific job')] public function analyzeChains(string $jobId): void { $analysis = $this->resolutionEngine->analyzeChains($jobId); echo "๐Ÿ” Chain Analysis for job: {$jobId}\n\n"; if (empty($analysis['chains'])) { echo " Job is not part of any chains\n"; return; } echo "๐Ÿ“Š Total chains: {$analysis['total_chains']}\n\n"; foreach ($analysis['chains'] as $chain) { $statusIcon = match($chain['status']) { 'pending' => 'โณ', 'running' => '๐Ÿ”„', 'completed' => 'โœ…', 'failed' => 'โŒ', default => 'โ“' }; echo "๐Ÿ”— {$statusIcon} {$chain['name']} ({$chain['chain_id']})\n"; echo " Status: {$chain['status']}\n"; echo " Mode: {$chain['execution_mode']}\n"; $position = $chain['job_position'] + 1; echo " Position: {$position}/{$chain['total_jobs']}\n"; if ($chain['next_job_after_current']) { echo " Next job: {$chain['next_job_after_current']}\n"; } echo " Progress: {$chain['progress']['completed_jobs']}/{$chain['progress']['total_jobs']} ({$chain['progress']['percentage']}%)\n\n"; } } #[ConsoleCommand(name: 'queue:chain:delete', description: 'Delete a job chain')] public function deleteChain(string $chainId): void { $chain = $this->chainManager->getChain($chainId); if (!$chain) { echo "โŒ Chain not found: {$chainId}\n"; return; } if ($chain->isRunning()) { echo "โŒ Cannot delete running chain. Chain must be completed or failed.\n"; return; } $this->chainManager->deleteChain($chainId); echo "โœ… Chain deleted: {$chainId}\n"; } #[ConsoleCommand(name: 'queue:chain:cleanup', description: 'Clean up old completed chains')] public function cleanupOldChains(int $olderThanDays = 30): void { $deletedCount = $this->chainManager->cleanupOldChains($olderThanDays); echo "๐Ÿงน Cleaned up old chains\n"; echo " Deleted: {$deletedCount} completed/failed chains older than {$olderThanDays} days\n"; } #[ConsoleCommand(name: 'queue:chain:progress', description: 'Show detailed progress of a chain')] public function showProgress(string $chainId): void { try { $progress = $this->chainManager->getChainProgress($chainId); echo "๐Ÿ“Š Chain Progress: {$progress['name']} ({$chainId})\n\n"; $statusIcon = match($progress['status']) { 'pending' => 'โณ', 'running' => '๐Ÿ”„', 'completed' => 'โœ…', 'failed' => 'โŒ', default => 'โ“' }; echo " Status: {$statusIcon} {$progress['status']}\n"; echo " Mode: {$progress['execution_mode']}\n"; echo " Progress: {$progress['completed_jobs']}/{$progress['total_jobs']} jobs ({$progress['percentage']}%)\n"; if ($progress['started_at']) { echo " Started: {$progress['started_at']}\n"; } if ($progress['completed_at']) { echo " Completed: {$progress['completed_at']}\n"; } // Progress bar $barLength = 30; $filledLength = (int) (($progress['percentage'] / 100) * $barLength); $bar = str_repeat('โ–ˆ', $filledLength) . str_repeat('โ–‘', $barLength - $filledLength); echo "\n [{$bar}] {$progress['percentage']}%\n"; } catch (\Exception $e) { echo "โŒ Failed to get chain progress: {$e->getMessage()}\n"; } } }