Files
michaelschiemer/src/Framework/Queue/Commands/JobCleanupCommands.php
Michael Schiemer 5050c7d73a docs: consolidate documentation into organized structure
- Move 12 markdown files from root to docs/ subdirectories
- Organize documentation by category:
  • docs/troubleshooting/ (1 file)  - Technical troubleshooting guides
  • docs/deployment/      (4 files) - Deployment and security documentation
  • docs/guides/          (3 files) - Feature-specific guides
  • docs/planning/        (4 files) - Planning and improvement proposals

Root directory cleanup:
- Reduced from 16 to 4 markdown files in root
- Only essential project files remain:
  • CLAUDE.md (AI instructions)
  • README.md (Main project readme)
  • CLEANUP_PLAN.md (Current cleanup plan)
  • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements)

This improves:
 Documentation discoverability
 Logical organization by purpose
 Clean root directory
 Better maintainability
2025-10-05 11:05:04 +02:00

328 lines
13 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace App\Framework\Queue\Commands;
use App\Framework\Console\ConsoleCommand;
use App\Framework\Console\ExitCode;
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Queue\Services\JobCleanupService;
use App\Framework\Queue\Services\JobMemoryManager;
use App\Framework\Performance\MemoryMonitor;
final readonly class JobCleanupCommands
{
public function __construct(
private JobCleanupService $cleanupService,
private JobMemoryManager $memoryManager,
private MemoryMonitor $memoryMonitor
) {}
#[ConsoleCommand(name: 'queue:cleanup:all', description: 'Run comprehensive queue cleanup with default retention periods')]
public function runComprehensiveCleanup(): ExitCode
{
echo "🧹 Starting Comprehensive Queue Cleanup\n\n";
try {
// Show current memory status
$memorySummary = $this->memoryMonitor->getSummary();
echo "💾 Memory Status:\n";
echo " Current: {$memorySummary->getCurrentHumanReadable()}\n";
echo " Available: {$memorySummary->getAvailableMemory()->toHumanReadable()}\n";
echo " Usage: {$memorySummary->getUsagePercentageFormatted()}\n\n";
// Show cleanup statistics
echo "📊 Cleanup Statistics:\n";
$stats = $this->cleanupService->getCleanupStatistics();
echo " Eligible for cleanup:\n";
echo " • Completed jobs: " . number_format($stats['eligible_completed_jobs']) . " (>{$stats['retention_days']['completed_jobs']} days)\n";
echo " • Failed jobs: " . number_format($stats['eligible_failed_jobs']) . " (>{$stats['retention_days']['failed_jobs']} days)\n";
echo " • Job metrics: " . number_format($stats['eligible_metrics']) . " (>{$stats['retention_days']['metrics']} days)\n";
echo " • Dead letter jobs: " . number_format($stats['eligible_dead_letter_jobs']) . " (>{$stats['retention_days']['dead_letter_jobs']} days)\n";
echo " • Total eligible: " . number_format($stats['total_eligible']) . "\n";
echo " • Estimated time: ~{$stats['estimated_cleanup_minutes']} minutes\n\n";
if ($stats['total_eligible'] === 0) {
echo "✅ No data eligible for cleanup\n";
return ExitCode::SUCCESS;
}
echo "🔄 Starting cleanup process...\n\n";
// Run comprehensive cleanup
$results = $this->cleanupService->runComprehensiveCleanup();
// Display results
echo "✅ Cleanup Results:\n";
echo " • Completed jobs deleted: " . number_format($results['completed_jobs']) . "\n";
echo " • Failed jobs deleted: " . number_format($results['failed_jobs']) . "\n";
echo " • Job metrics deleted: " . number_format($results['job_metrics']) . "\n";
echo " • Dead letter jobs deleted: " . number_format($results['dead_letter_jobs']) . "\n";
echo " • Total deleted: " . number_format($results['total_deleted']) . "\n\n";
echo "⏱️ Performance:\n";
echo " • Duration: {$results['duration_seconds']} seconds\n";
echo " • Memory used: {$results['memory_used']}\n";
echo " • Peak memory: {$results['memory_peak']}\n\n";
if (!empty($results['errors'])) {
echo "⚠️ Errors occurred:\n";
foreach ($results['errors'] as $error) {
echo "{$error}\n";
}
return ExitCode::GENERAL_ERROR;
}
echo "✅ Cleanup completed successfully!\n";
return ExitCode::SUCCESS;
} catch (\Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
return ExitCode::GENERAL_ERROR;
}
}
#[ConsoleCommand(name: 'queue:cleanup:completed', description: 'Clean up completed jobs older than specified days')]
public function cleanupCompletedJobs(int $days = 30): ExitCode
{
echo "🧹 Cleaning Completed Jobs\n\n";
try {
if ($days < 1) {
echo "❌ Days must be at least 1\n";
return ExitCode::INVALID_ARGUMENT;
}
echo "📊 Configuration:\n";
echo " • Delete completed jobs older than: {$days} days\n\n";
$duration = Duration::fromDays($days);
$deleted = $this->cleanupService->cleanupCompletedJobs($duration);
echo "✅ Cleanup Results:\n";
echo " • Completed jobs deleted: " . number_format($deleted) . "\n";
return ExitCode::SUCCESS;
} catch (\Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
return ExitCode::GENERAL_ERROR;
}
}
#[ConsoleCommand(name: 'queue:cleanup:failed', description: 'Clean up failed jobs older than specified days')]
public function cleanupFailedJobs(int $days = 90): ExitCode
{
echo "🧹 Cleaning Failed Jobs\n\n";
try {
if ($days < 1) {
echo "❌ Days must be at least 1\n";
return ExitCode::INVALID_ARGUMENT;
}
echo "📊 Configuration:\n";
echo " • Delete failed jobs older than: {$days} days\n\n";
$duration = Duration::fromDays($days);
$deleted = $this->cleanupService->cleanupFailedJobs($duration);
echo "✅ Cleanup Results:\n";
echo " • Failed jobs deleted: " . number_format($deleted) . "\n";
return ExitCode::SUCCESS;
} catch (\Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
return ExitCode::GENERAL_ERROR;
}
}
#[ConsoleCommand(name: 'queue:cleanup:metrics', description: 'Clean up job metrics older than specified days')]
public function cleanupMetrics(int $days = 180): ExitCode
{
echo "🧹 Cleaning Job Metrics\n\n";
try {
if ($days < 1) {
echo "❌ Days must be at least 1\n";
return ExitCode::INVALID_ARGUMENT;
}
echo "📊 Configuration:\n";
echo " • Delete metrics older than: {$days} days\n\n";
$duration = Duration::fromDays($days);
$deleted = $this->cleanupService->cleanupJobMetrics($duration);
echo "✅ Cleanup Results:\n";
echo " • Job metrics deleted: " . number_format($deleted) . "\n";
return ExitCode::SUCCESS;
} catch (\Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
return ExitCode::GENERAL_ERROR;
}
}
#[ConsoleCommand(name: 'queue:cleanup:deadletter', description: 'Clean up dead letter jobs older than specified days')]
public function cleanupDeadLetterJobs(int $days = 365): ExitCode
{
echo "🧹 Cleaning Dead Letter Jobs\n\n";
try {
if ($days < 1) {
echo "❌ Days must be at least 1\n";
return ExitCode::INVALID_ARGUMENT;
}
echo "📊 Configuration:\n";
echo " • Delete dead letter jobs older than: {$days} days\n\n";
$duration = Duration::fromDays($days);
$deleted = $this->cleanupService->cleanupDeadLetterJobs($duration);
echo "✅ Cleanup Results:\n";
echo " • Dead letter jobs deleted: " . number_format($deleted) . "\n";
return ExitCode::SUCCESS;
} catch (\Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
return ExitCode::GENERAL_ERROR;
}
}
#[ConsoleCommand(name: 'queue:cleanup:stats', description: 'Show cleanup statistics without performing cleanup')]
public function showCleanupStatistics(): ExitCode
{
echo "📊 Queue Cleanup Statistics\n\n";
try {
$stats = $this->cleanupService->getCleanupStatistics();
echo "📋 Retention Periods:\n";
echo " • Completed jobs: {$stats['retention_days']['completed_jobs']} days\n";
echo " • Failed jobs: {$stats['retention_days']['failed_jobs']} days\n";
echo " • Job metrics: {$stats['retention_days']['metrics']} days\n";
echo " • Dead letter jobs: {$stats['retention_days']['dead_letter_jobs']} days\n\n";
echo "🗑️ Eligible for Cleanup:\n";
echo " • Completed jobs: " . number_format($stats['eligible_completed_jobs']) . "\n";
echo " • Failed jobs: " . number_format($stats['eligible_failed_jobs']) . "\n";
echo " • Job metrics: " . number_format($stats['eligible_metrics']) . "\n";
echo " • Dead letter jobs: " . number_format($stats['eligible_dead_letter_jobs']) . "\n";
echo " • Total eligible: " . number_format($stats['total_eligible']) . "\n\n";
echo "⏱️ Estimated Cleanup Time: ~{$stats['estimated_cleanup_minutes']} minutes\n\n";
// Memory recommendations
$recommendations = $this->memoryManager->getMemoryRecommendations();
echo "💾 Memory Recommendations:\n";
echo " • Current usage: {$recommendations['current_usage']}\n";
echo " • Available memory: {$recommendations['available']}\n";
echo " • Priority: {$recommendations['priority']}\n";
foreach ($recommendations['recommendations'] as $rec) {
echo "\n 📌 {$rec['type']}:\n";
echo " {$rec['message']}\n";
if (!empty($rec['actions'])) {
echo " Actions:\n";
foreach ($rec['actions'] as $action) {
echo "{$action}\n";
}
}
}
return ExitCode::SUCCESS;
} catch (\Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
return ExitCode::GENERAL_ERROR;
}
}
#[ConsoleCommand(name: 'queue:memory:status', description: 'Show current memory status and recommendations')]
public function showMemoryStatus(): ExitCode
{
echo "💾 Queue Memory Status\n\n";
try {
// Get memory snapshot
$snapshot = $this->memoryManager->getJobMemorySnapshot('memory_status_check');
echo "📊 Current Memory Usage:\n";
echo " • Current: {$snapshot['current']} ({$snapshot['usage_percentage']}%)\n";
echo " • Peak: {$snapshot['peak']}\n";
echo " • Limit: {$snapshot['limit']}\n";
echo " • Available: {$snapshot['available']}\n";
echo " • Status: {$snapshot['status']}\n\n";
// Status indicators
if ($snapshot['is_critical']) {
echo "🔴 CRITICAL: Memory usage is critically high!\n\n";
} elseif ($snapshot['is_warning']) {
echo "🟡 WARNING: Memory usage is elevated.\n\n";
} else {
echo "🟢 NORMAL: Memory usage is within acceptable limits.\n\n";
}
// Get recommendations
$recommendations = $this->memoryManager->getMemoryRecommendations();
echo "📌 Recommendations:\n";
foreach ($recommendations['recommendations'] as $rec) {
echo "\n {$rec['type']}:\n";
echo " {$rec['message']}\n";
if (!empty($rec['actions'])) {
echo " Suggested actions:\n";
foreach ($rec['actions'] as $action) {
echo "{$action}\n";
}
}
}
return ExitCode::SUCCESS;
} catch (\Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
return ExitCode::GENERAL_ERROR;
}
}
#[ConsoleCommand(name: 'queue:memory:optimize', description: 'Optimize memory for job processing')]
public function optimizeMemory(): ExitCode
{
echo "🔧 Optimizing Queue Memory\n\n";
try {
echo "📊 Before Optimization:\n";
$beforeSnapshot = $this->memoryManager->getJobMemorySnapshot('before_optimization');
echo " • Memory: {$beforeSnapshot['current']} ({$beforeSnapshot['usage_percentage']}%)\n\n";
echo "🔄 Running optimization...\n";
$optimization = $this->memoryManager->optimizeForJob('manual_optimization');
echo "\n📊 After Optimization:\n";
echo " • Memory: {$optimization['after']}\n";
echo " • Freed: {$optimization['freed']}\n";
echo " • Usage before: {$optimization['usage_before']}\n";
echo " • Usage after: {$optimization['usage_after']}\n\n";
if ($optimization['freed_bytes'] > 0) {
echo "✅ Successfully freed {$optimization['freed']} of memory\n";
} else {
echo " No significant memory was freed (system may have already been optimized)\n";
}
return ExitCode::SUCCESS;
} catch (\Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
return ExitCode::GENERAL_ERROR;
}
}
}