はじめに
先日下記の記事を見まして、
packagist.orgのミラーサーバを立ててcomposer updateを18倍速くする #packagist - Qiita
composerがfile_get_contentsでjsonをダウンロードしていて、どうやらKeep-Aliveを使っていないし、並列ダウンロードもしていない
並列ダウンロードはさすがに簡単ではない(Composer 本体の修正が必要そう)けれど Keep-Alive なら curl でちょろっとできそうな気がしたのでやってみました。
それはそれとして、Composer の事を パッケージ管理ツール と呼ぶとツッコミを受けそうなので 依存関係管理ツール と呼んだほうが良さそうです。
Composer is not a package manager.
...
Thus, it is a dependency manager.
Composer プラグイン について
Composer にはプラグイン機構があります。
Setting up and using plugins - Composer
フレームワークのプラグインとかバンドルとかモジュールとか呼ばれる類のパッケージをインストールするときに、インストール先を Composer の本来の vendor/ ではなく、フレームワークが認識する所定のディレクトリに変更するためのカスタムインストーラーとしての用途が多いと思います。
CakePHP Composerを使ってプラグインをインストールする | junichi11.com
今回やりたいことは packagist.org からの json のダウンロードを file_get_contents
ではなく curl 拡張を使うようにすることなのですが、
PRE_FILE_DOWNLOAD
イベントを処理すればできそうです。
リンク先のサンプルコードを見た感じ、オレオレ Composer リポジトリを作った時にソースコードを S3 とかにホストして s3://
のような独自のスキームを使えるようにすることが想定されていそうですが、Composer の本来の http/https のダウンローダーも差し替えることができました。
また、フレームワークのためのカスタムインストーラーとして使用する場合はプロジェクトの composer.json の require にプラグインのパッケージ名を記述してプロジェクトローカルにプラグインをインストールすると思いますが、composer global require
でプラグインをインストールすればグローバルにプラグインを有効にすることができます。
Composer Curl Plugin
プラグインのコードは下記に置いています。
Packagist に登録しているので composer global require
でグローバルにインストールできます。
$ composer global require ngyuki/composer-curl-plugin:dev-master
効果の程を symfony/symfony
で確認してみます。
まずは symfony/symfony
をインストールします。
$ composer require symfony/symfony:\*
キャッシュを削除し、プラグインを使わずに(--no-plugins
を指定) composer update
してみます。
$ rm -fr ~/.composer/cache/repo/
$ composer update --dry-run --profile --no-plugins
:
Memory usage: 92.4MB (peak: 111.41MB), time: 139.99s
私の環境では2分強かかりました。
次に、プラグインが有効なままで composer update
してみます。
$ rm -fr ~/.composer/cache/repo/
$ composer update --dry-run --profile
:
Memory usage: 92.61MB (peak: 111.62MB), time: 67.21s
2倍ぐらい早くなりました。
さいごに
プラグインの中で curl のリソースを再利用しているので、複数回のダウンロードが Keep-Alive により共通のコネクションで行われるようになっています。
が、それだけで2倍も早くなるものですかね、PHP の http/https ストリームラッパーになにかしら遅くなる要因でもあるのかもしれません。
追記 2014/12/22
packagist.org 以外でも使えるようにしてみました。
デフォルトでは packagist.org でのみ有効になりますが、config で次のように追記しておくと、packagist.org 以外のミラーでも有効にできます。
$ composer config -g -e
{
"config": {
"curl-plugin": {
"hosts": [
"packagist.tojiru.net"
]
}
}
}
早速 packagist.tojiru.net ミラーで効果の程を確認してみます。
$ composer config -g repositories.packagist composer http://packagist.tojiru.net
まずはプラグインを使わずに試してみます。
$ rm -fr ~/.composer/cache/repo/
$ composer update --dry-run --profile --no-plugins
[7.2MB/0.08s] Loading composer repositories with package information
[7.6MB/0.15s] Updating dependencies (including require-dev)
[111.8MB/25.38s] Nothing to install or update
Memory usage: 93.01MB (peak: 112.05MB), time: 25.41s
私の環境では 25 秒ぐらいでした。
次に、プラグインを有効にして試してみます。
$ rm -fr ~/.composer/cache/repo/
$ composer update --dry-run --profile
[7.3MB/0.08s] Loading composer repositories with package information
[7.7MB/0.15s] Updating dependencies (including require-dev)
[112.0MB/18.01s] Nothing to install or update
Memory usage: 93.23MB (peak: 112.28MB), time: 18.04s
18 秒ぐらいになりました。
元々レイテンシの良いミラーだとそれほどの効果はなさそうです。