Skip to content

Commit 320359a

Browse files
committed
feat: use concurrent requests to get signed asset requests
1 parent 2122e8b commit 320359a

File tree

2 files changed

+45
-27
lines changed

2 files changed

+45
-27
lines changed

src/ApiClient.php

+43-23
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
use GuzzleHttp\ClientInterface;
1717
use GuzzleHttp\Exception\ClientException;
18+
use GuzzleHttp\Pool;
19+
use GuzzleHttp\Psr7\Request;
20+
use Psr\Http\Message\ResponseInterface;
1821
use Symfony\Component\Console\Exception\RuntimeException;
1922
use Tightenco\Collect\Support\Collection;
2023
use Ymir\Cli\Exception\ApiClientException;
@@ -712,13 +715,23 @@ public function getSecrets(int $projectId, string $environment): Collection
712715
*/
713716
public function getSignedAssetRequests(int $deploymentId, array $assets): Collection
714717
{
715-
$requests = $this->request('post', "/deployments/{$deploymentId}/signed-assets", ['assets' => $assets]);
716-
717-
if (!empty($assets) && empty($requests)) {
718-
throw new RuntimeException('Unable to get authorized asset requests from the Ymir API');
719-
}
718+
$requests = function (array $assets) use ($deploymentId) {
719+
foreach (array_chunk($assets, 500) as $chunkedAssets) {
720+
yield $this->createRequest('post', "/deployments/{$deploymentId}/signed-assets", ['assets' => $chunkedAssets]);
721+
}
722+
};
723+
$signedAssetRequests = [];
724+
725+
$pool = new Pool($this->client, $requests($assets), [
726+
'concurrency' => 10,
727+
'fulfilled' => function (ResponseInterface $response) use (&$signedAssetRequests) {
728+
$signedAssetRequests[] = $this->decodeResponse($response);
729+
},
730+
'options' => ['verify' => false],
731+
]);
732+
$pool->promise()->wait();
720733

721-
return $requests;
734+
return collect($signedAssetRequests)->collapse();
722735
}
723736

724737
/**
@@ -879,35 +892,42 @@ public function validateProjectConfiguration(ProjectConfiguration $projectConfig
879892
}
880893

881894
/**
882-
* Send a request to the Ymir API.
895+
* Create a PSR request object.
883896
*/
884-
private function request(string $method, string $uri, array $body = []): Collection
897+
private function createRequest(string $method, string $uri, array $body = []): Request
885898
{
886-
$method = strtolower($method);
887-
$options = [
888-
'base_uri' => $this->baseUrl,
889-
'headers' => [
890-
'Accept' => 'application/json',
891-
'Content-Type' => 'application/json',
892-
],
893-
'verify' => false,
899+
$headers = [
900+
'Accept' => 'application/json',
901+
'Content-Type' => 'application/json',
894902
];
895-
$uri = ltrim($uri, '/');
903+
$method = strtolower($method);
896904

897905
if ($this->cliConfiguration->hasAccessToken()) {
898-
$options['headers']['Authorization'] = 'Bearer '.$this->cliConfiguration->getAccessToken();
906+
$headers['Authorization'] = 'Bearer '.$this->cliConfiguration->getAccessToken();
899907
}
900908

901-
if (in_array($method, ['delete', 'post', 'put'])) {
902-
$options['json'] = $body;
903-
}
909+
return new Request($method, $this->baseUrl.ltrim($uri, '/'), $headers, in_array($method, ['delete', 'post', 'put']) ? (string) json_encode($body) : null);
910+
}
904911

912+
/**
913+
* Decode response returned by the Ymir API.
914+
*/
915+
private function decodeResponse(ResponseInterface $response): Collection
916+
{
917+
return collect(json_decode((string) $response->getBody(), true));
918+
}
919+
920+
/**
921+
* Send a request to the Ymir API.
922+
*/
923+
private function request(string $method, string $uri, array $body = []): Collection
924+
{
905925
try {
906-
$response = $this->client->request($method, $uri, $options);
926+
$response = $this->client->send($this->createRequest($method, $uri, $body), ['verify' => false]);
907927
} catch (ClientException $exception) {
908928
throw new ApiClientException($exception);
909929
}
910930

911-
return collect(json_decode((string) $response->getBody(), true));
931+
return $this->decodeResponse($response);
912932
}
913933
}

src/Deployment/ProcessAssetsStep.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,12 @@ public function perform(Collection $deployment, ConsoleOutput $output)
6262

6363
$output->writeStep('Getting signed asset URLs');
6464
$assetFiles = $this->getAssetFiles();
65-
$signedAssetRequests = $assetFiles->map(function (array $asset) {
65+
$signedAssetRequests = $this->apiClient->getSignedAssetRequests($deployment->get('id'), $assetFiles->map(function (array $asset) {
6666
return [
6767
'path' => $asset['relative_path'],
6868
'hash' => $asset['hash'],
6969
];
70-
})->chunk(500)->flatMap(function (Collection $chunkedAssetFiles) use ($deployment) {
71-
return $this->apiClient->getSignedAssetRequests($deployment->get('id'), $chunkedAssetFiles->all());
72-
});
70+
})->all());
7371

7472
if (count($assetFiles) !== count($signedAssetRequests)) {
7573
$output->warn('Warning: Not all asset files were processed successfully');

0 commit comments

Comments
 (0)