diff --git a/src/Service/Provider/GitLabProvider.php b/src/Service/Provider/GitLabProvider.php index cc03990..3ddf9fd 100644 --- a/src/Service/Provider/GitLabProvider.php +++ b/src/Service/Provider/GitLabProvider.php @@ -7,6 +7,7 @@ namespace App\Service\Provider; use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * Fetches the last 365 days of push/merge events from the GitLab REST API. @@ -46,9 +47,14 @@ final class GitLabProvider implements ProviderInterface } /** - * @return array date (Y-m-d) => event count + * @return array{baseUrl: string, userId: int, after: string, page: int, response: ResponseInterface} + * + * ponytail: the user-id lookup and event pagination stay sequential within + * this one provider (each page depends on the previous). Parallelism here + * only spans across providers; revisit only if GitLab pagination itself + * becomes the bottleneck. */ - public function fetch(): array + public function startFetch(): array { $baseUrl = rtrim($this->baseUrl !== '' ? $this->baseUrl : 'https://gitlab.com', '/'); @@ -64,21 +70,30 @@ final class GitLabProvider implements ProviderInterface throw new NotFoundHttpException("GitLab: user '{$this->username}' not found on $baseUrl"); } $userId = $users[0]['id']; + $after = (new \DateTimeImmutable('-365 days'))->format('Y-m-d'); + + $response = $this->client->request('GET', "$baseUrl/api/v4/users/$userId/events", [ + 'headers' => ['PRIVATE-TOKEN' => $this->token], + 'query' => [ + 'after' => $after, + 'per_page' => 100, + 'page' => 1, + ], + ]); + + return ['baseUrl' => $baseUrl, 'userId' => $userId, 'after' => $after, 'page' => 1, 'response' => $response]; + } + + /** + * @return array date (Y-m-d) => event count + */ + public function resolveFetch(mixed $handle): array + { + ['baseUrl' => $baseUrl, 'userId' => $userId, 'after' => $after, 'page' => $page, 'response' => $response] = $handle; $result = []; - $after = (new \DateTimeImmutable('-365 days'))->format('Y-m-d'); - $page = 1; do { - $response = $this->client->request('GET', "$baseUrl/api/v4/users/$userId/events", [ - 'headers' => ['PRIVATE-TOKEN' => $this->token], - 'query' => [ - 'after' => $after, - 'per_page' => 100, - 'page' => $page, - ], - ]); - $events = $response->toArray(); foreach ($events as $event) { @@ -87,6 +102,17 @@ final class GitLabProvider implements ProviderInterface } $page++; + + if (count($events) === 100) { + $response = $this->client->request('GET', "$baseUrl/api/v4/users/$userId/events", [ + 'headers' => ['PRIVATE-TOKEN' => $this->token], + 'query' => [ + 'after' => $after, + 'per_page' => 100, + 'page' => $page, + ], + ]); + } } while (count($events) === 100); $this->logger->info('GitLabProvider: fetched contributions', [