Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove doctrine annotation reader #203

Merged
merged 24 commits into from
Sep 11, 2023

Conversation

koriym
Copy link
Member

@koriym koriym commented Sep 6, 2023

  • Remove doctrine annotation reader from all code except ReflectionClass and ReflectionMethod
  • Support doctrine annotation v2
  • Bump coding standard version v11
  • Cleanup composer.json
  • Enhance RefectionClass functionality to not use annotation readers in other libraries depending Ray.Aop.
    • Add RefectionClass::ReflectionClass() method for annotations.
    • Add RefectionClass::getConstructor() method for annotations.
  • Create cached doctrine annotation reader.

In order to minimize version dependencies on other libraries such as doctirine v1/v2, psr/cache v1/v2/v3, and other symfony caches, and to enable efficient annotation usage that is useful both in development and in production, we decided that it would be better to keep our own (extremely) minimal cache reader for reading annotations Aop decided that it would be better to maintain its own extremely minimal cache reader for reading annotations, instead of using a generic cache library as before.

Aop/Ray.Di applications can use the following methods for fast annotation/attribute usage instead of using the doctrine/annotation reader as before.

doctirine v1/v2, psr/cache v1/v2/v3, 他symfony cacheなどの他のライブラリのバージョンの依存を最小化し、開発時でもプロダクションでも有用な効率的なアノテーション利用を可能にするために、アノテーションの読み込みにこれまでのように汎用のキャッシュライブラリを利用するのではなく、独自の極端に最小化したキャッシュリーダーを保持するのが良いと判断しました。

。Ray.Aop/Ray.Diを使ったアプリケーションはこれまでの様にdoctrine/annotationリーダーを使うのではなく以下のメソッドで高速にアノテーション/アトリビュート双方が利用できます。

  • Ray\Aop\ReflectionClass::getAnnotation()
  • Ray\Aop\ReflectionClass::getAnnotations()
  • Ray\Aop\ReflectionMethod::getAnnotation()
  • Ray\Aop\ReflectionMethod::getAnnotations()

背景

php8でdoctrine/annotationの代替となるPHP8ネイティブのアトリビュートの機能がリリースされ、これからannotationの重要度は低下していく前提があります。また他にも他のライブラリの依存対応の問題もあります。

  • doctrine/annotationはv2になり、その対応はRay.Aopに依存しているパッケージ全てに必要があります。
  • doctrine/annotation v1及びv2にはPsrCacheReaderが添付されていますが、これを利用するためにはv1, v2, v3のpsr/logとそれぞれに対応したsymfony/cache(v5=psr/cache1-2, v6=psr/cache2-3)の依存が必要です。
  • 開発時はキャッシュしなくても問題ないという前提に立っていまたが、かなりの、(数十秒単位以上)でパフォーマンスインパクトを与える場合があることも分かってきました。
  • psr/cacheにはTTLの機能が必要ですが、アノテーションはファイルに変更がない限りは内容は変わらないのpsr/cacheよりずっと小さいキャッシュでも可能です。

https://packagist.org/packages/psr/cache

シナリオ

annotationの理由が必須な場合で開発時

ファイルの時間をベースにしたキャッシュでキャッシュ削除などのメンテナンスが不要です。

annotationの理由が必須な場合でプロダクション時

何もしなくてもPHPファイルキャッシュが機能しますが、さらに最適化が必要な場合はブートストラップで以下のコードのように最適化したアノテーションリーダーをセットします。

SevericeLocator::setReader($apcuAnnotationReader);`

annotationの理由が不要な場合

rectorなどで既存のアノテーションを全てアトリビュートに変更した場合は、以下のコードのように最適化したアノテーションリーダーをセットします。

SevericeLocator::setReader(new AttributeReader);`

いずれの場合も広報互換性は保たれ、アノテーションを取り除いた後でもパフォーマンスインパクトは最小に抑えられると考えられます。

@koriym koriym changed the title Support doctrine annotation Support doctrine annotation v2 Sep 6, 2023
@codecov
Copy link

codecov bot commented Sep 6, 2023

Codecov Report

Patch coverage: 100.00% and no project coverage change.

Comparison is base (18f58cf) 100.00% compared to head (eb89d47) 100.00%.
Report is 3 commits behind head on 2.x.

Additional details and impacted files
@@             Coverage Diff             @@
##                 2.x      #203   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
- Complexity       162       168    +6     
===========================================
  Files             30        30           
  Lines            457       470   +13     
===========================================
+ Hits             457       470   +13     
Files Changed Coverage Δ
src/AnnotatedMatcher.php 100.00% <ø> (ø)
src/AopClass.php 100.00% <ø> (ø)
src/AopClassName.php 100.00% <ø> (ø)
src/CallIntercept.php 100.00% <ø> (ø)
src/CodeGen.php 100.00% <ø> (ø)
src/CodeVisitor.php 100.00% <ø> (ø)
src/Matcher.php 100.00% <ø> (ø)
src/Matcher/AnyMatcher.php 100.00% <ø> (ø)
src/Matcher/LogicalAndMatcher.php 100.00% <ø> (ø)
src/Matcher/LogicalNotMatcher.php 100.00% <ø> (ø)
... and 15 more

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@koriym koriym force-pushed the support_doctrine_annotation_v2 branch from e87032e to bf9775d Compare September 6, 2023 09:47
@koriym koriym force-pushed the support_doctrine_annotation_v2 branch from 5275585 to 890ce9e Compare September 7, 2023 20:00
@koriym koriym changed the title Support doctrine annotation v2 Remove doctrine annotation reader Sep 8, 2023
* Created to avoid "version dependencies" on the original doctrine/annotation v1/v2, psr/log and other cache libraries.

* This leader is valid in both development and production environments.
@koriym koriym force-pushed the support_doctrine_annotation_v2 branch from de2eecd to 20db177 Compare September 8, 2023 15:15
@koriym koriym force-pushed the support_doctrine_annotation_v2 branch from 20db177 to a805754 Compare September 9, 2023 03:32
@ray-di ray-di deleted a comment from sonarcloud bot Sep 9, 2023
Copy link
Member

@NaokiTsuchiya NaokiTsuchiya left a comment

Choose a reason for hiding this comment

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

シナリオに記載の内容は、ドキュメントとして含めてしまっても良さそうな内容と思いました!

/** @var array<string, array<object>> */
private $loadedAnnotations = [];

/** @var int[] */
private $loadedFilemtimes = [];

public function __construct(Reader $reader, CacheItemPoolInterface $cache, bool $debug = false)
public function __construct(Reader $reader, Cache $cache)
Copy link
Member

Choose a reason for hiding this comment

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

Cache も interface があれば、例えば APCu に変更したいときに APCuCache だけを実装すればOKになるかなと思いましたがどうですかね。。?

Copy link
Member Author

Choose a reason for hiding this comment

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

アノテーションリーダーからアトリビュートの過渡期で、より高速を望むなら、

A) rectorなどでアトリビュートにするか または B)オリジナルのキャッシュリーダー PsrCachedReader を使うか

という選択肢があり、ここでB)を選択しなかったのは「他のライブラリに依存するより最小で自己完結的にした方が良い」と考えたからです。ここで新しいインターフェイスを導入するのは"自己完結"に背くような気もして入れてない感じです。いつもは可能な限り汎用品を使って租結合にしてますが、ここは違うところでは?と考えました。どうでしょうか?

Copy link
Member Author

Choose a reason for hiding this comment

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

"シナリオ"をパフォーマンスに含めました。

eb89d47

@koriym koriym merged commit 0961e4a into ray-di:2.x Sep 11, 2023
19 checks passed
@koriym koriym deleted the support_doctrine_annotation_v2 branch September 11, 2023 15:53
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.

None yet

2 participants