diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-07-18 18:41:40 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-07-18 18:41:40 +0900 |
| commit | 8cf9f977d90d0a8e8bfcb868a7ebcd4e1309c517 (patch) | |
| tree | 6856e67a3216f227651889c083cfa8f23170f026 /crates/shirabe/tests | |
| parent | 307e66847dd5e00ad1890b6a64d3ac7192a03efc (diff) | |
| download | php-shirabe-8cf9f977d90d0a8e8bfcb868a7ebcd4e1309c517.tar.gz php-shirabe-8cf9f977d90d0a8e8bfcb868a7ebcd4e1309c517.tar.zst php-shirabe-8cf9f977d90d0a8e8bfcb868a7ebcd4e1309c517.zip | |
perf(installation-manager): run executeBatch operation chains concurrently
executeBatch now builds one future per operation — the PHP promise
chain prepare -> install/update/uninstall -> cleanup -> repo->write,
including the '<Op> of <pkg> failed' rejection handler covering the
chain up to cleanup — and drives the whole batch through
waitOnPromises()/Loop::wait, so archive extraction (the unzip
subprocesses gated by ProcessExecutor's semaphore) finally overlaps
across packages. Alias operations stay synchronous in the collection
loop like PHP.
The shared repository is threaded through the chains as
RefCell<&mut dyn InstalledRepositoryInterface>: execute() wraps the
incoming &mut once, and InstallerInterface::install/update/uninstall
take the cell so implementations borrow it only in their synchronous
head/tail, never across an await. InstallationManager's own
install/update/uninstall/download/get_installer/get_install_path/
mark_for_notification move to &self (cache and notifiable_packages
behind RefCell) so every chain can capture &self.
WritableRepositoryInterface::write and the InstallationManagerInterface
get_install_path it relies on lose their &mut manager requirement —
the per-op repo->write inside the chains only reads install paths.
Warm-cache create-project laravel/laravel: the package-operations
phase (109 installs) drops from ~3.0-3.8s serial to ~1.9s, on par
with real Composer (~2.1s) measured back-to-back; the resulting
vendor tree, installed.json included, stays byte-identical to
Composer's (diff -rq clean).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/tests')
6 files changed, 27 insertions, 27 deletions
diff --git a/crates/shirabe/tests/autoload/autoload_generator_test.rs b/crates/shirabe/tests/autoload/autoload_generator_test.rs index 9e41e3dd..09ff2101 100644 --- a/crates/shirabe/tests/autoload/autoload_generator_test.rs +++ b/crates/shirabe/tests/autoload/autoload_generator_test.rs @@ -64,7 +64,7 @@ impl InstallerInterface for InstallPathStubInstaller { async fn install( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) @@ -72,7 +72,7 @@ impl InstallerInterface for InstallPathStubInstaller { async fn update( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, _initial: PackageInterfaceHandle, _target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -81,7 +81,7 @@ impl InstallerInterface for InstallPathStubInstaller { async fn uninstall( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) diff --git a/crates/shirabe/tests/common/test_case.rs b/crates/shirabe/tests/common/test_case.rs index 4adee211..a8bcb6a8 100644 --- a/crates/shirabe/tests/common/test_case.rs +++ b/crates/shirabe/tests/common/test_case.rs @@ -216,7 +216,7 @@ pub fn create_installed_json( let io = null_io(); let im = installation_manager(&io); - repo.write(dev_mode, &mut im.borrow_mut()).unwrap(); + repo.write(dev_mode, &im.borrow()).unwrap(); } /// ref: TestCase::createComposerLock diff --git a/crates/shirabe/tests/installer/installation_manager_test.rs b/crates/shirabe/tests/installer/installation_manager_test.rs index 3ed2f25b..a39eaddf 100644 --- a/crates/shirabe/tests/installer/installation_manager_test.rs +++ b/crates/shirabe/tests/installer/installation_manager_test.rs @@ -100,7 +100,7 @@ impl InstallerInterface for MockInstaller { async fn install( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { MockInstaller::install(self, package) @@ -108,7 +108,7 @@ impl InstallerInterface for MockInstaller { async fn update( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -117,7 +117,7 @@ impl InstallerInterface for MockInstaller { async fn uninstall( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { MockInstaller::uninstall(self, package) @@ -200,7 +200,7 @@ impl InstallerInterface for BinaryInstaller { async fn install( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) @@ -208,7 +208,7 @@ impl InstallerInterface for BinaryInstaller { async fn update( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, _initial: PackageInterfaceHandle, _target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -217,7 +217,7 @@ impl InstallerInterface for BinaryInstaller { async fn uninstall( &self, - _repo: &mut dyn InstalledRepositoryInterface, + _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) @@ -326,7 +326,7 @@ fn test_install() { let operation = InstallOperation::new(package.clone()); let mut repository = InstalledArrayRepository::new().unwrap(); - run(manager.install(&mut repository, &operation)); + run(manager.install(&std::cell::RefCell::new(&mut repository as &mut dyn InstalledRepositoryInterface), &operation)); } #[test] @@ -358,7 +358,7 @@ fn test_update_with_equal_types() { let operation = UpdateOperation::new(initial.clone(), target.clone()); let mut repository = InstalledArrayRepository::new().unwrap(); - run(manager.update(&mut repository, &operation)); + run(manager.update(&std::cell::RefCell::new(&mut repository as &mut dyn InstalledRepositoryInterface), &operation)); } #[test] @@ -400,7 +400,7 @@ fn test_update_with_not_equal_types() { let operation = UpdateOperation::new(initial.clone(), target.clone()); let mut repository = InstalledArrayRepository::new().unwrap(); - run(manager.update(&mut repository, &operation)); + run(manager.update(&std::cell::RefCell::new(&mut repository as &mut dyn InstalledRepositoryInterface), &operation)); } #[test] @@ -428,7 +428,7 @@ fn test_uninstall() { let operation = UninstallOperation::new(package.clone()); let mut repository = InstalledArrayRepository::new().unwrap(); - run(manager.uninstall(&mut repository, &operation)); + run(manager.uninstall(&std::cell::RefCell::new(&mut repository as &mut dyn InstalledRepositoryInterface), &operation)); } #[test] diff --git a/crates/shirabe/tests/installer/library_installer_test.rs b/crates/shirabe/tests/installer/library_installer_test.rs index b9e3caa8..c233ebcd 100644 --- a/crates/shirabe/tests/installer/library_installer_test.rs +++ b/crates/shirabe/tests/installer/library_installer_test.rs @@ -242,7 +242,7 @@ fn test_install() { let mut repository = InstalledArrayRepository::new().unwrap(); - run(library.install(&mut repository, package.clone())).unwrap(); + run(library.install(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), package.clone())).unwrap(); // PHP asserts repository->addPackage was called once with $package. assert!(repository.has_package(package)); @@ -299,7 +299,7 @@ fn test_update() { let library = LibraryInstaller::new(setup.io.clone(), setup.composer.clone(), None, None, None); - run(library.update(&mut repository, initial.clone(), target.clone())).unwrap(); + run(library.update(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), initial.clone(), target.clone())).unwrap(); assert!( std::path::Path::new(&new_target_dir).exists(), @@ -320,7 +320,7 @@ fn test_update() { ); // Updating again, with the initial package no longer installed, fails. - assert!(run(library.update(&mut repository, initial, target)).is_err()); + assert!(run(library.update(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), initial, target)).is_err()); tear_down(&mut setup); } @@ -353,12 +353,12 @@ fn test_uninstall() { let mut repository = InstalledArrayRepository::new().unwrap(); repository.add_package(package.clone()).unwrap(); - run(library.uninstall(&mut repository, package.clone())).unwrap(); + run(library.uninstall(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), package.clone())).unwrap(); assert!(!repository.has_package(package.clone())); // Uninstalling again, with the package no longer installed, fails. - assert!(run(library.uninstall(&mut repository, package)).is_err()); + assert!(run(library.uninstall(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), package)).is_err()); tear_down(&mut setup); } diff --git a/crates/shirabe/tests/installer/metapackage_installer_test.rs b/crates/shirabe/tests/installer/metapackage_installer_test.rs index 3c1f0efe..a3806ec8 100644 --- a/crates/shirabe/tests/installer/metapackage_installer_test.rs +++ b/crates/shirabe/tests/installer/metapackage_installer_test.rs @@ -22,7 +22,7 @@ fn test_install() { let installer = installer(); let mut repository = InstalledArrayRepository::new_with_packages(vec![]).unwrap(); - run(installer.install(&mut repository, package.clone())).unwrap(); + run(installer.install(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), package.clone())).unwrap(); assert!(repository.has_package(package)); } @@ -35,13 +35,13 @@ fn test_update() { let mut repository = InstalledArrayRepository::new_with_packages(vec![initial.clone()]).unwrap(); - run(installer.update(&mut repository, initial.clone(), target.clone())).unwrap(); + run(installer.update(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), initial.clone(), target.clone())).unwrap(); assert!(!repository.has_package(initial.clone())); assert!(repository.has_package(target.clone())); // Updating again, with the initial package no longer installed, fails. - assert!(run(installer.update(&mut repository, initial, target)).is_err()); + assert!(run(installer.update(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), initial, target)).is_err()); } #[test] @@ -51,10 +51,10 @@ fn test_uninstall() { let mut repository = InstalledArrayRepository::new_with_packages(vec![package.clone()]).unwrap(); - run(installer.uninstall(&mut repository, package.clone())).unwrap(); + run(installer.uninstall(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), package.clone())).unwrap(); assert!(!repository.has_package(package.clone())); // Uninstalling again, with the package no longer installed, fails. - assert!(run(installer.uninstall(&mut repository, package)).is_err()); + assert!(run(installer.uninstall(&std::cell::RefCell::new(&mut repository as &mut dyn shirabe::repository::InstalledRepositoryInterface), package)).is_err()); } diff --git a/crates/shirabe/tests/repository/filesystem_repository_test.rs b/crates/shirabe/tests/repository/filesystem_repository_test.rs index f9d03ecd..6e7370dc 100644 --- a/crates/shirabe/tests/repository/filesystem_repository_test.rs +++ b/crates/shirabe/tests/repository/filesystem_repository_test.rs @@ -110,7 +110,7 @@ mockall::mock! { run_scripts: bool, download_only: bool, ) -> anyhow::Result<()>; - fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String>; + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String>; fn set_output_progress(&mut self, output_progress: bool); fn notify_installs(&mut self, io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>); } @@ -151,7 +151,7 @@ fn test_repository_write() { repository .add_package(get_package("mypkg", "0.1.10")) .unwrap(); - repository.write(true, &mut im).unwrap(); + repository.write(true, &im).unwrap(); let written = std::fs::read_to_string(&json_path).unwrap(); let actual: serde_json::Value = serde_json::from_str(&written).unwrap(); @@ -312,7 +312,7 @@ fn test_repository_writes_installed_php() { Some(format!("vendor/{}", package.get_name())) }); - repository.write(true, &mut im).unwrap(); + repository.write(true, &im).unwrap(); let expected = std::fs::read_to_string(format!( "{}/../../composer/tests/Composer/Test/Repository/Fixtures/installed.php", |
