Browse Source

Avoid fetching non-existing files multiple times

Jordi Boggiano 5 years ago
parent
commit
8f09f3764b
1 changed files with 12 additions and 0 deletions
  1. 12 0
      src/Composer/Repository/ComposerRepository.php

+ 12 - 0
src/Composer/Repository/ComposerRepository.php

@@ -65,6 +65,12 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
     private $rootData;
     private $rootData;
     private $hasPartialPackages;
     private $hasPartialPackages;
     private $partialPackagesByName;
     private $partialPackagesByName;
+
+    /**
+     * @var array list of package names which returned a 404 and should not be re-fetched in case loadPackage is called several times
+     *          useful for v2 metadata repositories with lazy providers
+     */
+    private $packagesNotFoundCache = array();
     /**
     /**
      * TODO v3 should make this private once we can drop PHP 5.3 support
      * TODO v3 should make this private once we can drop PHP 5.3 support
      * @private
      * @private
@@ -1079,6 +1085,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
     {
     {
         $retries = 3;
         $retries = 3;
 
 
+        if (isset($this->packagesNotFoundCache[$filename])) {
+            return \React\Promise\Util::promiseFor(array('packages' => array()));
+        }
+
         $httpDownloader = $this->httpDownloader;
         $httpDownloader = $this->httpDownloader;
         if ($this->eventDispatcher) {
         if ($this->eventDispatcher) {
             $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename);
             $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename);
@@ -1095,6 +1105,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
         $accept = function ($response) use ($io, $url, $cache, $cacheKey) {
         $accept = function ($response) use ($io, $url, $cache, $cacheKey) {
             // package not found is acceptable for a v2 protocol repository
             // package not found is acceptable for a v2 protocol repository
             if ($response->getStatusCode() === 404) {
             if ($response->getStatusCode() === 404) {
+                $this->packagesNotFoundCache[$filename] = true;
                 return array('packages' => array());
                 return array('packages' => array());
             }
             }
 
 
@@ -1119,6 +1130,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
 
 
         $reject = function ($e) use (&$retries, $httpDownloader, $filename, $options, &$reject, $accept, $io, $url, &$degradedMode) {
         $reject = function ($e) use (&$retries, $httpDownloader, $filename, $options, &$reject, $accept, $io, $url, &$degradedMode) {
             if ($e instanceof TransportException && $e->getStatusCode() === 404) {
             if ($e instanceof TransportException && $e->getStatusCode() === 404) {
+                $this->packagesNotFoundCache[$filename] = true;
                 return false;
                 return false;
             }
             }