Skip to content

Conversation

@Seldaek
Copy link
Member

@Seldaek Seldaek commented Jun 23, 2025

Only create autoloaders when needed, and avoid creating duplicate autoloaders.

In pathological cases like declaring a post-package-install script as "Foo::bar", it would classmap-scan the whole project on every package being installed, causing 200ms of delay at every package. Trying this on a repo here this PR improves a fresh install time from 38 down to 9seconds, which is quite dramatic. I suppose other cases where large classmaps or listener-heavy plugins are present might also see significant speedups.

Targetting 2.9 though because it does carry some risk of regression in case I missed a corner.

Refs #8587

@stof
Copy link
Contributor

stof commented Jun 23, 2025

For the case in #8587 (comment), I think another improvement could be done: composer run-script (either used explicitly or through a script alias) should never need to make an autoloader, as it is not running as part of the composer installation that can change the installed packages.

@Seldaek
Copy link
Member Author

Seldaek commented Jun 23, 2025

composer run-script (either used explicitly or through a script alias) should never need to make an autoloader, as it is not running as part of the composer installation that can change the installed packages.

yeah I thought about this but it is most often used for binaries which are anyway now skipping the autoloader completely, so I don't think it is worth detecting this special case (especially as it is maybe not so easy, we lack that context inside EventDispatcher).. As creating a single autoloader is often relatively cheap, the main problem is when it keeps recreating them.

The other issue is that we do not actually load the project's autoloader, so this would fail if we do not create an autoloader inside run-script.

@Seldaek Seldaek force-pushed the event_autoload_perf branch from f983c75 to 8ead554 Compare June 23, 2025 14:25
Only create autoloaders when needed, and avoid creating duplicate autoloaders

Refs composer#8587
@Seldaek Seldaek force-pushed the event_autoload_perf branch from 8ead554 to 3372a31 Compare June 25, 2025 07:41
@Seldaek Seldaek merged commit 2ac8f49 into composer:main Jun 25, 2025
20 checks passed
@eiriksm
Copy link
Contributor

eiriksm commented Nov 13, 2025

I am about 98% sure this broke our (outdated) scripthandler, which had in it a require to a class being installed with composer

Like so:

use DrupalFinder\DrupalFinder;
use Symfony\Component\Filesystem\Filesystem;

// ...

$fs = new Filesystem();
$drupalFinder = new DrupalFinder();

after CI got 2.9.0:

Error: Class 'DrupalFinder\DrupalFinder' not found

In ScriptHandler.php line 20:
                                               
Error: r]                                      
  Class 'DrupalFinder\DrupalFinder' not found  
                                               

Exception trace:
  at /home/runner/work/bkf/bkf/scripts/composer/ScriptHandler.php:20
 DrupalProject\composer\ScriptHandler::createRequiredFiles() at phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:527

@driskell
Copy link
Contributor

driskell commented Nov 13, 2025

@eiriksm I raised in #12602 with a full tiny reproduction scenario so hopefully the (amazing) composer team has everything they need to fix this :)

@driskell
Copy link
Contributor

A workaround for Drupal is to remove the checkComposerVersion pre-install and pre-update scripts - this will prevent the wrong autoloader generating and fix the post-install and post-update scripts. Of course once composer is updated with a fix likely you'll want to put the pre scripts back in.

$generator->setDevMode($event->isDevMode());
$hash .= $event->isDevMode() ? '/dev' : '';
}
$hash = hash('sha256', $hash);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth just adding in the event type here? As in, if it's pre or post - as inherently the package list is highly likely to be different between them. This would ensure the post hook generates a new autoloader.

I think issue is the package list for local repository is technically the same before an install as it is after - the only difference is that the vendor folder exists after - which from an autoloader perspective I guess is completely different? Perhaps the above is the best way to fix the issue? Or if there's perhaps a flag somewhere to say if install has been completed or not?

@eiriksm
Copy link
Contributor

eiriksm commented Nov 13, 2025

Awesome.

Also for the record. My comment reads a bit, eheh, short, when I tried to jot this down before running out the door. Sorry about that. I also have the opinion that the composer team is amazing, just to state that ❤️

@eiriksm
Copy link
Contributor

eiriksm commented Nov 13, 2025

...and can I just also point out that projects that are using that scripthandler usually do that because they have inherited the setup from the good old drupal-composer project. Now we have official ways of doing it, and that probably does not break in this way (at least I think it would not do that)

In my case, the script is almost completely useless, so it's a good occasion to clean them up a bit 🤓

@Seldaek
Copy link
Member Author

Seldaek commented Nov 13, 2025

My comment reads a bit, eheh, short,

No worries, just wish more people tested snapshots or RCs as that'd reduce the need for such stressful moments, but aside from that all good :D

@Seldaek Seldaek deleted the event_autoload_perf branch November 13, 2025 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants