-
-
Notifications
You must be signed in to change notification settings - Fork 27
refactor(sentry): optimize SingletonAspect with match expression #1049
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
refactor(sentry): optimize SingletonAspect with match expression #1049
Conversation
…class handling Replace the complex closure-based singleton instance reset logic with a more efficient match expression that explicitly handles different Sentry class types: - Direct instantiation for singleton classes (HubAdapter, IntegrationRegistry) - Simplified TraceMetrics creation - Bypass context handling for enum types - Default to original behavior for unknown classes This improves performance, readability, and reduces the overhead of reflection-based property manipulation while maintaining coroutine safety through Context. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Walkthrough将多个文件中对协程延迟执行的调用从 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–30 分钟
Possibly related PRs
Suggested reviewers
诗歌
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (4)**/*.php📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
src/**/src/**/*.php📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
src/*/src/**/*.php📄 CodeRabbit inference engine (CLAUDE.md)
Files:
src/**/*.php📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (1)📚 Learning: 2025-12-12T05:33:43.947ZApplied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
🔇 Additional comments (3)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 PHPStan (2.1.33)At least one path must be specified to analyse. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR attempts to refactor the SingletonAspect to use a match expression instead of the original closure-based approach, claiming to improve performance and readability. However, the refactoring introduces critical bugs that break the singleton pattern implementation for Sentry SDK classes.
Key Issues:
- Direct class instantiation bypasses the singleton pattern's
getInstance()method, breaking initialization logic - The argument check logic was inadvertently changed in a way that affects falsy value handling
- Redundant enum case handling that provides no benefit over the default case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/sentry/src/Aspect/SingletonAspect.php (1)
55-62: 建议从切面拦截列表中移除枚举类。第 55-62 行的枚举类(CheckInStatus、EventType、MonitorScheduleUnit 等)直接调用
$proceedingJoinPoint->process(),没有任何特殊处理。然而这些类仍然在$classes数组(第 22-32 行)中,导致切面会拦截它们的调用。根据 PR 目标描述:"bypass context handling for enum types to improve performance",但当前实现仍然拦截了这些枚举类,只是在拦截后直接放行。这会产生不必要的性能开销。
🔎 建议从 $classes 数组中移除枚举类以真正提升性能
public array $classes = [ - \Sentry\CheckInStatus::class . '::getInstance', - \Sentry\EventType::class . '::getInstance', - \Sentry\MonitorScheduleUnit::class . '::getInstance', \Sentry\Integration\IntegrationRegistry::class . '::getInstance', - \Sentry\Logs\LogLevel::class . '::getInstance', \Sentry\Metrics\TraceMetrics::class . '::getInstance', \Sentry\State\HubAdapter::class . '::getInstance', - \Sentry\Tracing\SpanStatus::class . '::getInstance', - \Sentry\Tracing\TransactionSource::class . '::getInstance', - \Sentry\Transport\ResultStatus::class . '::getInstance', - \Sentry\Unit::class . '::getInstance', ];同时简化 match 表达式:
return match ($className) { // Singleton Classes \Sentry\State\HubAdapter::class, \Sentry\Integration\IntegrationRegistry::class => Context::getOrSet($key, function () use ($className) { return Closure::bind(fn () => new $className(), null, $className)(); }), \Sentry\Metrics\TraceMetrics::class => Context::getOrSet($key, function () use ($className) { return new $className(); }), - - // Enums - \Sentry\CheckInStatus::class, - \Sentry\EventType::class, - \Sentry\MonitorScheduleUnit::class, - \Sentry\Logs\LogLevel::class, - \Sentry\Tracing\SpanStatus::class, - \Sentry\Tracing\TransactionSource::class, - \Sentry\Transport\ResultStatus::class, - \Sentry\Unit::class => $proceedingJoinPoint->process(), default => $proceedingJoinPoint->process(), };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/sentry/src/Aspect/SingletonAspect.php
🧰 Additional context used
📓 Path-based instructions (4)
**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.php: All PHP files must includedeclare(strict_types=1)at the top
Use PSR-12 coding standards for PHP code formatting
Use 4-space indentation with short array syntax in PHP code
Use.php-cs-fixer.phpconfiguration for PHP code formattingAll PHP files must include a strict_types declaration at the top
**/*.php: Follow project PHP coding standard enforced by php-cs-fixer with PSR-12 style, 4-space indentation, and short array syntax
Maintain type coverage by updating or adding tests when public APIs change; ensurecomposer test:typesstays green before pushing
Files:
src/sentry/src/Aspect/SingletonAspect.php
src/**/src/**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use namespace pattern
FriendsOfHyperf\{ComponentName}for all component classes
Files:
src/sentry/src/Aspect/SingletonAspect.php
src/*/src/**/*.php
📄 CodeRabbit inference engine (CLAUDE.md)
src/*/src/**/*.php: Namespace convention for components must follow FriendsOfHyperf{ComponentName}
All code must be coroutine-safe and avoid global state without proper context management, blocking I/O operations, and non-coroutine-safe third-party libraries without wrappers
Use Hyperf's Context API for request-scoped data instead of global state
Follows PSR-12 coding standards and use PHP-CS-Fixer for automatic formatting
Use PHPStan at maximum level for static analysis
Ensure component namespace doesn't conflict with existing Hyperf components or other packages in the ecosystem
Integrate deeply with Hyperf's Dependency Injection container for service registration
Leverage Hyperf's AOP (Aspect-Oriented Programming) for cross-cutting concerns via aspects defined in ConfigProvider
Use Hyperf's Event System to register listeners for framework events in components
All code must support coroutine-based concurrency using Swoole/Swow compatibility
Files:
src/sentry/src/Aspect/SingletonAspect.php
src/**/*.php
📄 CodeRabbit inference engine (AGENTS.md)
Each component lives in its own subdirectory with PSR-4 namespaces matching
FriendsOfHyperf\*
Files:
src/sentry/src/Aspect/SingletonAspect.php
🧠 Learnings (1)
📚 Learning: 2025-12-12T05:33:43.947Z
Learnt from: CR
Repo: friendsofhyperf/components PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-12T05:33:43.947Z
Learning: Applies to src/*/src/**/*.php : Leverage Hyperf's AOP (Aspect-Oriented Programming) for cross-cutting concerns via aspects defined in ConfigProvider
Applied to files:
src/sentry/src/Aspect/SingletonAspect.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.3 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.1 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.2 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.1 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.2 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.3 with Swoole 6.1.3
- GitHub Check: Agent
- GitHub Check: Seer Code Review
🔇 Additional comments (1)
src/sentry/src/Aspect/SingletonAspect.php (1)
44-64: 使用 match 表达式提升代码可读性。使用
match表达式替代之前的逻辑,使代码更清晰、更易维护。针对不同类型的 Sentry 类采用不同的处理策略,同时保持协程安全性。结构清晰,易于扩展。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
src/sentry/src/Aspect/SingletonAspect.php (2)
40-42: 修复逻辑取反错误,避免数组访问异常。条件被取反但函数体保持不变,导致逻辑错误:
- 原代码:
if (isset($arguments[0]))→ 当参数存在时追加到 key- 新代码:
if (! array_key_exists(0, $arguments))→ 当参数不存在时尝试追加$arguments[0]这会在
$arguments为空或不包含索引 0 时抛出 "Undefined array key 0" 错误。🔎 修复条件逻辑
- if (! array_key_exists(0, $arguments)) { + if (array_key_exists(0, $arguments)) { $key .= '#' . $arguments[0]; }
46-52: 调用原始 getInstance() 而非直接实例化,以保持单例模式完整性。直接实例化绕过了 Sentry SDK 的
getInstance()方法,存在以下问题:
- 跳过了
getInstance()中的初始化逻辑- 未正确重置 Sentry SDK 内部的单例状态
- 破坏了 Sentry SDK 预期的单例行为
正确做法是在 Hyperf Context 中存储实例以确保协程安全,同时重置内部单例状态后调用原始的
getInstance()。🔎 建议的修复方案
- \Sentry\State\HubAdapter::class, - \Sentry\Integration\IntegrationRegistry::class => Context::getOrSet($key, function () use ($className) { - return Closure::bind(fn () => new $className(), null, $className)(); + \Sentry\State\HubAdapter::class, + \Sentry\Integration\IntegrationRegistry::class => Context::getOrSet($key, function () use ($className, $proceedingJoinPoint) { + // 重置内部单例状态后调用原始 getInstance() + Closure::bind(static function () { + self::$instance = null; + }, null, $className)(); + + return $proceedingJoinPoint->process(); }), - \Sentry\Metrics\TraceMetrics::class => Context::getOrSet($key, function () use ($className) { - return new $className(); + \Sentry\Metrics\TraceMetrics::class => Context::getOrSet($key, function () use ($className, $proceedingJoinPoint) { + // 重置内部单例状态后调用原始 getInstance() + Closure::bind(static function () { + self::$instance = null; + }, null, $className)(); + + return $proceedingJoinPoint->process(); }),
🧹 Nitpick comments (1)
src/sentry/src/Aspect/SingletonAspect.php (1)
55-62: 从 $classes 数组中移除枚举类以实现真正的性能优化。枚举类在 match 表达式中仅调用
$proceedingJoinPoint->process(),与 default 分支行为完全相同。但它们仍在第 22-32 行的$classes数组中,这意味着:
- 每次枚举调用
getInstance()仍会触发切面拦截- 产生不必要的切面调用开销
- PR 目标中提到的"为枚举类型绕过上下文处理以提升性能"并未实现
建议将以下枚举类从
$classes数组中移除,让它们完全不经过切面拦截:
\Sentry\CheckInStatus::class\Sentry\EventType::class\Sentry\MonitorScheduleUnit::class\Sentry\Logs\LogLevel::class\Sentry\Tracing\SpanStatus::class\Sentry\Tracing\TransactionSource::class\Sentry\Transport\ResultStatus::class\Sentry\Unit::class枚举是不可变的,不需要协程安全的上下文处理。
🔎 建议的重构方案
在
$classes数组中移除枚举类(保留单例类):public array $classes = [ - \Sentry\CheckInStatus::class . '::getInstance', - \Sentry\EventType::class . '::getInstance', - \Sentry\MonitorScheduleUnit::class . '::getInstance', \Sentry\Integration\IntegrationRegistry::class . '::getInstance', - \Sentry\Logs\LogLevel::class . '::getInstance', \Sentry\Metrics\TraceMetrics::class . '::getInstance', \Sentry\State\HubAdapter::class . '::getInstance', - \Sentry\Tracing\SpanStatus::class . '::getInstance', - \Sentry\Tracing\TransactionSource::class . '::getInstance', - \Sentry\Transport\ResultStatus::class . '::getInstance', - \Sentry\Unit::class . '::getInstance', ];然后从 match 表达式中移除枚举分支:
return match ($className) { // Singleton Classes \Sentry\State\HubAdapter::class, \Sentry\Integration\IntegrationRegistry::class => Context::getOrSet($key, function () use ($className) { return Closure::bind(fn () => new $className(), null, $className)(); }), \Sentry\Metrics\TraceMetrics::class => Context::getOrSet($key, function () use ($className) { return new $className(); }), - - // Enums - \Sentry\CheckInStatus::class, - \Sentry\EventType::class, - \Sentry\MonitorScheduleUnit::class, - \Sentry\Logs\LogLevel::class, - \Sentry\Tracing\SpanStatus::class, - \Sentry\Tracing\TransactionSource::class, - \Sentry\Transport\ResultStatus::class, - \Sentry\Unit::class => $proceedingJoinPoint->process(), default => $proceedingJoinPoint->process(), };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/sentry/src/Aspect/SingletonAspect.php
🧰 Additional context used
📓 Path-based instructions (4)
**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.php: All PHP files must includedeclare(strict_types=1)at the top
Use PSR-12 coding standards for PHP code formatting
Use 4-space indentation with short array syntax in PHP code
Use.php-cs-fixer.phpconfiguration for PHP code formattingAll PHP files must include a strict_types declaration at the top
**/*.php: Follow project PHP coding standard enforced by php-cs-fixer with PSR-12 style, 4-space indentation, and short array syntax
Maintain type coverage by updating or adding tests when public APIs change; ensurecomposer test:typesstays green before pushing
Files:
src/sentry/src/Aspect/SingletonAspect.php
src/**/src/**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use namespace pattern
FriendsOfHyperf\{ComponentName}for all component classes
Files:
src/sentry/src/Aspect/SingletonAspect.php
src/*/src/**/*.php
📄 CodeRabbit inference engine (CLAUDE.md)
src/*/src/**/*.php: Namespace convention for components must follow FriendsOfHyperf{ComponentName}
All code must be coroutine-safe and avoid global state without proper context management, blocking I/O operations, and non-coroutine-safe third-party libraries without wrappers
Use Hyperf's Context API for request-scoped data instead of global state
Follows PSR-12 coding standards and use PHP-CS-Fixer for automatic formatting
Use PHPStan at maximum level for static analysis
Ensure component namespace doesn't conflict with existing Hyperf components or other packages in the ecosystem
Integrate deeply with Hyperf's Dependency Injection container for service registration
Leverage Hyperf's AOP (Aspect-Oriented Programming) for cross-cutting concerns via aspects defined in ConfigProvider
Use Hyperf's Event System to register listeners for framework events in components
All code must support coroutine-based concurrency using Swoole/Swow compatibility
Files:
src/sentry/src/Aspect/SingletonAspect.php
src/**/*.php
📄 CodeRabbit inference engine (AGENTS.md)
Each component lives in its own subdirectory with PSR-4 namespaces matching
FriendsOfHyperf\*
Files:
src/sentry/src/Aspect/SingletonAspect.php
🧠 Learnings (1)
📚 Learning: 2025-12-12T05:33:43.947Z
Learnt from: CR
Repo: friendsofhyperf/components PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-12T05:33:43.947Z
Learning: Applies to src/*/src/**/*.php : Leverage Hyperf's AOP (Aspect-Oriented Programming) for cross-cutting concerns via aspects defined in ConfigProvider
Applied to files:
src/sentry/src/Aspect/SingletonAspect.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
- GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.2 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.3 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.1 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.2 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.3 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.1 with Swoole 6.1.3
- GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
- GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
- GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
- GitHub Check: Seer Code Review
| $arguments = $proceedingJoinPoint->getArguments(); | ||
|
|
||
| if (isset($arguments[0])) { | ||
| if (! array_key_exists(0, $arguments)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: The condition ! array_key_exists(0, $arguments) is the inverse of the previous logic. It incorrectly executes the following block when no arguments are passed, causing an error.
Severity: CRITICAL | Confidence: High
🔍 Detailed Analysis
The logic to check for the existence of arguments in singleton getInstance methods has been inverted. The new condition if (! array_key_exists(0, $arguments)) evaluates to true when no arguments are provided. This causes the code to attempt to access $arguments[0] on an empty array, which will trigger a PHP "undefined array key" warning or error on every call to methods like TraceMetrics::getInstance(). This breaks the intended caching behavior.
💡 Suggested Fix
The conditional logic should be corrected to check for the existence of the argument before attempting to access it. Change if (! array_key_exists(0, $arguments)) to if (array_key_exists(0, $arguments)) to correctly append the argument to the cache key only when it is present.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/sentry/src/Aspect/SingletonAspect.php#L42
Potential issue: The logic to check for the existence of arguments in singleton
`getInstance` methods has been inverted. The new condition `if (! array_key_exists(0,
$arguments))` evaluates to `true` when no arguments are provided. This causes the code
to attempt to access `$arguments[0]` on an empty array, which will trigger a PHP
"undefined array key" warning or error on every call to methods like
`TraceMetrics::getInstance()`. This breaks the intended caching behavior.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 7807594
* refactor(sentry): optimize SingletonAspect with match expression for class handling Replace the complex closure-based singleton instance reset logic with a more efficient match expression that explicitly handles different Sentry class types: - Direct instantiation for singleton classes (HubAdapter, IntegrationRegistry) - Simplified TraceMetrics creation - Bypass context handling for enum types - Default to original behavior for unknown classes This improves performance, readability, and reduces the overhead of reflection-based property manipulation while maintaining coroutine safety through Context. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor(sentry): replace Co::defer with defer function for coroutine handling * fix(sentry): correct condition check for argument existence in SingletonAspect * refactor(sentry): clean up SingletonAspect by commenting out unused singleton classes and enums --------- Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
Summary
Changes
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
发布说明
✏️ Tip: You can customize this high-level summary in your review settings.