option('dry-run'); $execute = (bool) $this->option('execute'); if ($dryRun === $execute) { $this->error('Pass exactly one of --dry-run or --execute.'); return self::FAILURE; } $target = (string) $this->argument('target'); $force = (bool) $this->option('force'); $this->info(sprintf( '[redis-cleanup-orphans] prefix=%s connection=default target=%s force=%s mode=%s', (string) config('database.redis.options.prefix'), $target, $force ? 'yes' : 'no', $dryRun ? 'dry-run' : 'execute' )); try { $plan = $execute ? $cleanup->execute($target, $force) : $cleanup->plan($target, $force); } catch (RuntimeException $e) { $this->error($e->getMessage()); Log::warning('[redis-cleanup-orphans] refused', ['target' => $target, 'error' => $e->getMessage()]); return self::FAILURE; } $this->line('logical_key='.$plan['logical_key']); $this->line('notify_key='.$plan['notify_key']); $this->line('llen='.$plan['llen'].' reserved='.$plan['reserved'].' delayed='.$plan['delayed']); $this->line('sampled='.$plan['sampled'].' est_bytes='.$plan['est_bytes']); $this->line('classes='.json_encode($plan['classes'])); if ($plan['unexpected_classes'] !== []) { $this->warn('unexpected_classes='.json_encode($plan['unexpected_classes'])); } if ($plan['errors'] !== []) { $this->error('errors='.implode(',', $plan['errors'])); } if ($execute) { $this->info('unlinked='.($plan['unlinked'] ?? 0)); } Log::info('[redis-cleanup-orphans] completed', [ 'target' => $target, 'dry_run' => $dryRun, 'llen' => $plan['llen'], 'errors' => $plan['errors'], 'unlinked' => $plan['unlinked'] ?? 0, ]); return ($plan['errors'] === [] || $dryRun) ? self::SUCCESS : self::FAILURE; } }