1111use CodedMonkey \Dirigent \Message \ResolveDistribution ;
1212use Symfony \Component \DependencyInjection \Attribute \Autowire ;
1313use Symfony \Component \Filesystem \Filesystem ;
14+ use Symfony \Component \Lock \LockFactory ;
1415use Symfony \Component \Messenger \MessageBusInterface ;
1516use Symfony \Component \Messenger \Stamp \TransportNamesStamp ;
1617
@@ -23,6 +24,7 @@ public function __construct(
2324 private MessageBusInterface $ messenger ,
2425 private ComposerClient $ composer ,
2526 private DistributionRepository $ distributionRepository ,
27+ private LockFactory $ lockFactory ,
2628 #[Autowire(param: 'dirigent.distributions.dev_versions ' )]
2729 private bool $ includeDevVersions ,
2830 #[Autowire(param: 'dirigent.storage.path ' )]
@@ -74,23 +76,34 @@ public function resolve(Metadata $metadata, string $reference, string $type, boo
7476 return false ;
7577 }
7678
77- if (null === $ distribution = $ this ->distributionRepository ->findOneByReferenceAndType ($ metadata , $ reference , $ type )) {
78- $ distribution = new Distribution ($ metadata , $ reference , $ type );
79- }
80-
8179 $ distributionUrl = $ metadata ->getDistributionUrl ();
8280 $ path = $ this ->path ($ metadata , $ reference , $ type );
8381
84- $ this ->filesystem ->mkdir (dirname ($ path ));
82+ $ lock = $ this ->lockFactory ->createLock ('distribution. ' . hash ('sha256 ' , $ path ), ttl: null );
83+ $ lock ->acquire (blocking: true );
84+
85+ try {
86+ if ($ this ->filesystem ->exists ($ path )) {
87+ return true ;
88+ }
89+
90+ if (null === $ distribution = $ this ->distributionRepository ->findOneByReferenceAndType ($ metadata , $ reference , $ type )) {
91+ $ distribution = new Distribution ($ metadata , $ reference , $ type );
92+ }
8593
86- $ httpDownloader = $ this ->composer ->createHttpDownloader ();
87- $ httpDownloader ->copy ($ distributionUrl , $ path );
94+ $ this ->filesystem ->mkdir (dirname ($ path ));
8895
89- $ distribution -> setSource ( $ distributionUrl );
90- $ distribution -> setResolvedAt ( );
96+ $ httpDownloader = $ this -> composer -> createHttpDownloader ( );
97+ $ httpDownloader -> copy ( $ distributionUrl , $ path );
9198
92- $ this ->distributionRepository ->save ($ distribution , true );
99+ $ distribution ->setSource ($ distributionUrl );
100+ $ distribution ->setResolvedAt ();
93101
94- return true ;
102+ $ this ->distributionRepository ->save ($ distribution , true );
103+
104+ return true ;
105+ } finally {
106+ $ lock ->release ();
107+ }
95108 }
96109}
0 commit comments