api->getUpdates(timeout: $timeout, marker: $marker); foreach ($updateList->updates as $update) { try { $this->dispatcher->dispatch($update); } catch (\Throwable $e) { $this->logger->error('Error dispatching update', [ 'message' => $e->getMessage(), 'exception' => $e, ]); } } return $updateList->marker; } /** * Starts a long-polling loop to process updates. * This method will run indefinitely until the script is terminated. * * @param int $timeout Timeout in seconds for long polling (0-90). * @param int|null $marker Initial marker. Pass `null` to get updates you didn't get yet. */ public function handle(int $timeout = 90, ?int $marker = null): void { $this->listenSignals(); // @phpstan-ignore-next-line while (true) { try { $marker = $this->processUpdates($timeout, $marker); } catch (NetworkException $e) { $this->logger->error( 'Long-polling network error: {message}', ['message' => $e->getMessage(), 'exception' => $e], ); sleep(5); } catch (\Exception $e) { $this->logger->error( 'An error occurred during long-polling: {message}', ['message' => $e->getMessage(), 'exception' => $e], ); sleep(1); } } } /** * @codeCoverageIgnore */ protected function listenSignals(): void { if (extension_loaded('pcntl')) { pcntl_async_signals(true); $kill = static function () { exit(0); }; pcntl_signal(SIGINT, $kill); pcntl_signal(SIGQUIT, $kill); pcntl_signal(SIGTERM, $kill); } } }