[StatisticsController::class, 'robot'], 'schedules' => [SchedulesController::class, 'robot'], 'relayschedules' => [RelayController::class, 'robot'], 'posts' => [PostsSiteController::class, 'robot'], 'chatban' => [InteractivityController::class, 'robot'], 'api-limits' => [ApiController::class, 'cleaner'], 'campaigns' => [ContentsController::class, 'robots'], 'djs' => [DJController::class, 'robots'], ]; /* Robos que dividem o trabalho pela lista de portas ativas. */ private const POR_PORTA = ['statistics', 'schedules']; public function handle(): int { $nome = (string) $this->argument('robot'); if (! isset(self::ROBOTS[$nome])) { $this->error('robo desconhecido: ' . $nome); $this->line('disponiveis: ' . implode(', ', array_keys(self::ROBOTS))); return self::FAILURE; } [$classe, $metodo] = self::ROBOTS[$nome]; $arg = (string) $this->argument('arg'); if ($this->option('de')) { if (! in_array($nome, self::POR_PORTA, true)) { $this->error($nome . ' nao divide o trabalho por porta; passe o recorte a mao'); return self::FAILURE; } $arg = $this->fatia((int) $this->option('de'), (int) $this->option('parte')); } if ($this->option('simular')) { $this->line($nome . ' usaria o recorte ' . $arg); return self::SUCCESS; } $inicio = microtime(true); $this->line('[' . now()->format('Y-m-d H:i:s') . '] ' . $nome . ' ' . $arg); try { /* o container resolve o que o metodo pedir, inclusive Request; o recorte vai pelo nome, e o metodo que nao tiver esse parametro simplesmente o ignora */ app()->call([app($classe), $metodo], ['arg' => $arg]); } catch (Throwable $erro) { Log::error('robot ' . $nome . ' falhou', [ 'arg' => $arg, 'erro' => $erro->getMessage(), 'onde' => $erro->getFile() . ':' . $erro->getLine(), ]); $this->error($erro->getMessage()); return self::FAILURE; } $this->info(sprintf('%s terminou em %.1fs', $nome, microtime(true) - $inicio)); return self::SUCCESS; } /** * O recorte sai da contagem de portas ativas, e nao de numeros escritos * a mao na crontab. Assim entrar de 2 mil para 5 mil portas nao pede * nenhuma linha nova: muda so em quantas partes o trabalho e dividido. */ private function fatia(int $de, int $parte): string { $de = max(1, $de); $parte = min(max(1, $parte), $de); $total = DB::table('streamings')->where('status', '=', '1')->count(); $tamanho = (int) ceil($total / $de); return (($parte - 1) * $tamanho) . '-' . $tamanho; } }