Skip to content

Commit 3448e41

Browse files
committed
Add async handling for resolving of distributions
1 parent da36da8 commit 3448e41

5 files changed

Lines changed: 99 additions & 6 deletions

File tree

‎src/Controller/ApiController.php‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,7 @@ public function packageDistribution(Request $request, string $reference, string
135135
throw $this->createNotFoundException();
136136
}
137137

138-
if ($metadata->getVersion()->isDevelopment() && !$this->getParameter('dirigent.distributions.dev_versions')) {
139-
throw $this->createNotFoundException();
140-
}
141-
142-
if (!$this->distributionResolver->resolve($metadata, $type)) {
138+
if (!$this->distributionResolver->resolve($metadata, $type, async: $this->getParameter('dirigent.distributions.async_api_requests'))) {
143139
throw $this->createNotFoundException();
144140
}
145141
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CodedMonkey\Dirigent\Message;
6+
7+
use Symfony\Component\Messenger\Attribute\AsMessage;
8+
9+
#[AsMessage]
10+
readonly class ResolveDistribution
11+
{
12+
public function __construct(
13+
public int $metadataId,
14+
public string $type,
15+
) {
16+
}
17+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CodedMonkey\Dirigent\Message;
6+
7+
use CodedMonkey\Dirigent\Doctrine\Repository\MetadataRepository;
8+
use CodedMonkey\Dirigent\Package\PackageDistributionResolver;
9+
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
10+
11+
#[AsMessageHandler]
12+
readonly class ResolveDistributionHandler
13+
{
14+
public function __construct(
15+
private MetadataRepository $metadataRepository,
16+
private PackageDistributionResolver $distributionResolver,
17+
) {
18+
}
19+
20+
public function __invoke(ResolveDistribution $message): void
21+
{
22+
if (null === $metadata = $this->metadataRepository->find($message->metadataId)) {
23+
return;
24+
}
25+
26+
$this->distributionResolver->resolve($metadata, $message->type, async: false);
27+
}
28+
}

‎src/Package/PackageDistributionResolver.php‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,22 @@
66

77
use CodedMonkey\Dirigent\Composer\ComposerClient;
88
use CodedMonkey\Dirigent\Doctrine\Entity\Metadata;
9+
use CodedMonkey\Dirigent\Message\ResolveDistribution;
910
use Symfony\Component\DependencyInjection\Attribute\Autowire;
1011
use Symfony\Component\Filesystem\Filesystem;
12+
use Symfony\Component\Messenger\MessageBusInterface;
13+
use Symfony\Component\Messenger\Stamp\TransportNamesStamp;
1114

1215
readonly class PackageDistributionResolver
1316
{
1417
private Filesystem $filesystem;
1518
private string $storagePath;
1619

1720
public function __construct(
21+
private MessageBusInterface $messenger,
1822
private ComposerClient $composer,
23+
#[Autowire(param: 'dirigent.distributions.dev_versions')]
24+
private bool $includeDevVersions,
1925
#[Autowire(param: 'dirigent.storage.path')]
2026
string $storagePath,
2127
) {
@@ -33,7 +39,7 @@ public function path(string $packageName, string $versionName, string $reference
3339
return "{$this->storagePath}/{$packageName}/{$versionName}-{$reference}.{$type}";
3440
}
3541

36-
public function resolve(Metadata $metadata, string $type): bool
42+
public function resolve(Metadata $metadata, string $type, bool $async): bool
3743
{
3844
$package = $metadata->getPackage();
3945
$packageName = $package->getName();
@@ -48,6 +54,20 @@ public function resolve(Metadata $metadata, string $type): bool
4854
return false;
4955
}
5056

57+
if ($metadata->getVersion()->isDevelopment() && !$this->includeDevVersions) {
58+
return false;
59+
}
60+
61+
if ($async) {
62+
// Resolve the distribution asynchronously so it's available in the future now that we know it was requested
63+
$this->messenger->dispatch(new ResolveDistribution($metadata->getId(), $type), [
64+
new TransportNamesStamp('async'),
65+
]);
66+
67+
// Still return false so the service resolving the distribution doesn't try to fetch it anyway
68+
return false;
69+
}
70+
5171
$distributionUrl = $metadata->getDistributionUrl();
5272
$path = $this->path($packageName, $versionName, $reference, $type);
5373

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CodedMonkey\Dirigent\Tests\UnitTests\Message;
6+
7+
use CodedMonkey\Dirigent\Doctrine\Repository\MetadataRepository;
8+
use CodedMonkey\Dirigent\Message\ResolveDistribution;
9+
use CodedMonkey\Dirigent\Message\ResolveDistributionHandler;
10+
use CodedMonkey\Dirigent\Package\PackageDistributionResolver;
11+
use PHPUnit\Framework\Attributes\CoversClass;
12+
use PHPUnit\Framework\TestCase;
13+
14+
#[CoversClass(ResolveDistributionHandler::class)]
15+
class ResolveDistributionHandlerTest extends TestCase
16+
{
17+
public function testInvokeIgnoresMissingMetadata(): void
18+
{
19+
$metadataRepository = $this->createMock(MetadataRepository::class);
20+
$metadataRepository->expects(self::once())
21+
->method('find')
22+
->with(42)
23+
->willReturn(null);
24+
25+
$distributionResolver = $this->createMock(PackageDistributionResolver::class);
26+
$distributionResolver->expects(self::never())->method('resolve');
27+
28+
$handler = new ResolveDistributionHandler($metadataRepository, $distributionResolver);
29+
30+
$handler(new ResolveDistribution(42, 'reference', 'zip'));
31+
}
32+
}

0 commit comments

Comments
 (0)