`PREBUILT_CACHE` weaves and writes the cache when a class is missing from it (fails on read-only file systems)

オープン
#808 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@lisachenko がすでに取り組んでいます。

2026年11月5日 から。

  • #834 @lisachenko による — オープン

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
php
領域
backend

調査の方向性

Read src/Instrument/ClassLoading/SourceTransformingLoader.php around saveToCache() and src/Instrument/ClassLoading/CachePathManager.php around flushCacheState(), then inspect the existing cache tests. First decide how PREBUILT_CACHE should handle cache misses and missing cached files; done means the chosen behavior avoids the reported write or warning, the documentation matches, and the acceptance tests pass. An open linked pull request is already addressing this issue.

索引モデルが issue の本文から書いたものです。

説明

Bug

Found while benchmarking with goaop/shop-demo (PHP 8.5.12, framework b755e57). Follow-up of #680, which fixed the same promise for the advisor caches only.

Problem

Features::PREBUILT_CACHE is documented as "never writes to the cache directory … Works on read-only file systems" (docs/configuration.md:37, src/Aop/Features.php). A class below the include paths that is missing from the cache is nevertheless woven by the request that loads it, and the result is written:

  • SourceTransformingLoader::saveToCache() writes the woven source with no PREBUILT_CACHE guard (src/Instrument/ClassLoading/SourceTransformingLoader.php:311-346, write at :333);
  • CachePathManager::flushCacheState() rewrites both metadata files at shutdown; it is guarded by is_writable($this->cacheDir) only (src/Instrument/ClassLoading/CachePathManager.php:616).

On a read-only file system, CacheFileWriter::write() throws WeavingException::cacheDirectoryNotCreated / cacheFileNotWritten (src/Core/Cache/CacheFileWriter.php:61,76), so the request fails (from reading the code; not reproducible as root here).

Reproduction (writable cache)

cd shop-demo
APP_MODE=prebuilt vendor/bin/aspect cache:warmup:aop config/bootstrap.php
# add an advised class after the warm-up, e.g. src/Service/LateService.php (matched by
# MonitoringAspect's execution(public App\Service\*->*(*))), then load it with APP_MODE=prebuilt

Result: the request loads the parser, the transformers, the matcher and the aspects (234 files included for a script that only boots the kernel and creates this one object), writes var/cache/prebuilt/src/Service/LateService.php and LateServiceOriginalTrait.php, and rewrites _include.cache.

Related variant: when a record exists but its cached file is gone, PREBUILT_CACHE trusts the record, file_get_contents() of the missing file raises a warning (SourceTransformingLoader.php:298), and the class is woven and written again.

Proposal (decide which)

  1. Serve without saving: with PREBUILT_CACHE, a miss is woven and the woven source is emitted by the stream filter as usual, but nothing is written and nothing is flushed. The behaviour stays correct, the file system stays untouched, and each such request pays for weaving.
  2. Fail fast: throw a dedicated WeavingException (see src/Aop/Exception/AGENTS.md) that names the class and says to rebuild the cache with cache:warmup:aop.

Option 1 matches the documented contract; option 2 surfaces an incomplete deployment immediately. Either way, the missing-cached-file variant should take the same path instead of raising a warning.

Acceptance

  • With PREBUILT_CACHE, a miss writes nothing: tested on a read-only vfs and on real disk.
  • docs/configuration.md matches the behaviour.
  • composer test, composer analyze.

Estimate

Medium: SourceTransformingLoader::saveToCache() and CachePathManager::flushCacheState() guards, plus a decision on the semantics and tests.


Generated by Claude Code

主要言語
PHP
スター
1.7k
フォーク
166
平均マージ
1日 1時間
マージ済み PR(30日)
42

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

goaop/framework のほかの issue

goaop/framework の issue をすべて見る

似ている issue

PHP の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。