When using Artifactory to handle composer repositories (both as a public cached version and a private one), artifactory does not pass the correct headers for the package.json files (i.e. the modified date). This means that when composer comes to do an update, it will never use the version that it cached from Artifactory because it was unable to insert a timestamp into it. This means that doing a "composer up" can take a considerable amount of time for projects with large dependency trees.
Attached is an example of two different composer.json files. One (p1) uses packagist and the other (p2) uses artifactory. When doing a composer up on the packagist one, it takes approximately 2 seconds from start to finish and, as expected, updates nothing (see p1/bla.txt for the verbose output of that process). You'll notice that most of the package JSON files are simply read from the cache.
Now, compare this to the Artifactory version. This one took about 20 seconds to complete, again, with no updates performed as expected. It's about x10 slower using Artifactory. If you look at p2/bla.txt the output of this process shows that it had to read from Artifactory for each package.
20 seconds may not seem like a long time, but this is a composer.json file with one dependency in it. As an example of how painful this is, for one repository that I'm working with, the average amount of time to do a composer update using Artifactory is about 10 minutes!
After downloading the package information file from Artifactory, it takes (if it exists) the Last-Modified header from that package request and injects it into the cached JSON file. When composer update is run for a second time, it doesn't have this value in the file (because Artifactory isn't passing it) so it will never use the cached version and will always have to request the file again from Artifactory.
- Create composer default remote repository
- configure config.json and auth.json for remote
- perform a composer up on p2 with following composer.json
(notice this request takes around 20 seconds)
4. Now remove config.json and auth.json and perform a composer up on p1 with following composer.json
(This request finishes much quicker)