Problem
大規模テストスイート(2,700+ tests)でこのパッケージを使用すると、OpenApiSpecLoader::$cache にデコードされたJSON specが静的に保持され、テスト全体を通じてメモリから解放されません。
当プロジェクトでは front.json(5.5MB)をデコードした PHP 配列だけで 約16MB を消費しており、extension全体で 約20MB のメモリオーバーヘッドが発生しています。
通常実行: 515.50 MB
--no-extensions: 495.50 MB
差分: ~20 MB
Root Cause
OpenApiSpecLoader の $cache が static array で保持されており、一度ロードされたspecはプロセス終了まで解放されません。
// OpenApiSpecLoader.php
private static array $cache = [];
public static function load(string $specName): array
{
if (isset(self::$cache[$specName])) {
return self::$cache[$specName];
}
// ... file_get_contents + json_decode ...
self::$cache[$specName] = $decoded;
return $decoded;
}
加えて、OpenApiResponseValidator がアサーションごとに新規インスタンスを生成し、OpenApiPathMatcher がその都度正規表現をコンパイルしています。
Suggestions
-
WeakReference / オンデマンドロード: specを WeakReference で保持するか、バリデーション完了後にキャッシュをクリアするオプションを提供する
-
PathMatcher の再利用: OpenApiPathMatcher をspec単位でキャッシュし、毎回の正規表現コンパイルを避ける
-
必要な部分だけロード: バリデーション対象のエンドポイントに必要なスキーマだけを抽出し、spec全体をメモリに保持しない(lazy loading)
-
spec キャッシュの手動クリアAPI: OpenApiSpecLoader::reset() は存在するが自動的に呼ばれない。テストクラス間でリセットするオプションを提供する
Environment
- PHP 8.4
- PHPUnit 13.0.5
- openapi-contract-testing v0.10.0
- front.json: 5.5MB (144,497 lines)