feat(sentry): add SentrySdkAspect for coroutine-safe SDK usage#1063
feat(sentry): add SentrySdkAspect for coroutine-safe SDK usage#1063huangdijia merged 8 commits intomainfrom
Conversation
Add an aspect that intercepts SentrySdk::init, ::setCurrentHub, and ::getRuntimeContextManager to make them coroutine-safe using Hyperf's Context API and RuntimeContextManager. This ensures that Sentry SDK works correctly in a coroutine environment by storing the runtime context manager in Hyperf's context storage.
Walkthrough将 Changes
Sequence Diagram(s)sequenceDiagram
participant App as 应用
participant Aspect as SentrySdkAspect
participant Context as Hyperf Context
participant Manager as RuntimeContextManager
participant Hub as HubInterface
participant SDK as SentrySdk
App->>Aspect: 调用 SentrySdk::init()
Aspect->>Hub: 创建 Hub 实例
Aspect->>Manager: 创建 RuntimeContextManager(Hub)
Aspect->>Context: 存储 Manager
Aspect->>App: 返回 Hub
App->>Aspect: 调用 SentrySdk::setCurrentHub(hub)
Aspect->>Context: 获取 Manager
Aspect->>Manager: 设置当前 Hub
Aspect->>App: 返回 hub
App->>Aspect: 调用 SentrySdk::getRuntimeContextManager()
Aspect->>Context: 查询 Manager
alt 存在
Aspect->>App: 返回 Manager
else 不存在
Aspect->>Hub: 创建 Hub
Aspect->>Manager: 创建 Manager
Aspect->>Context: 存储 Manager
Aspect->>App: 返回 Manager
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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.40)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.
Pull request overview
This pull request attempts to add coroutine-safety to Sentry SDK usage by introducing a SentrySdkAspect that intercepts SentrySdk methods and uses Hyperf's Context API with RuntimeContextManager. However, this approach is fundamentally flawed because the codebase already implements coroutine-safety for SentrySdk through a class_map override (registered in ConfigProvider line 80, implemented in class_map/SentrySdk.php).
Changes:
- Added
SentrySdkAspectclass to intercept SentrySdk methods - Registered the aspect in ConfigProvider
- Attempted to use RuntimeContextManager for coroutine isolation
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| src/sentry/src/ConfigProvider.php | Registers the new SentrySdkAspect (conflicts with existing class_map) |
| src/sentry/src/Aspect/SentrySdkAspect.php | New aspect attempting to make SentrySdk coroutine-safe (redundant and incompatible) |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/sentry/src/Aspect/SentrySdkAspect.php (1)
43-43: 可选:移除未使用形参,消除静态分析噪音。
handleInit()与handleGetRuntimeContextManager()的$proceedingJoinPoint未被使用,可删掉以减少 PHPMD 告警。♻️ 建议修改
- 'init' => $this->handleInit($proceedingJoinPoint), + 'init' => $this->handleInit(), 'setCurrentHub' => $this->handleSetCurrentHub($proceedingJoinPoint), - 'getRuntimeContextManager' => $this->handleGetRuntimeContextManager($proceedingJoinPoint), + 'getRuntimeContextManager' => $this->handleGetRuntimeContextManager(), - private function handleInit(ProceedingJoinPoint $proceedingJoinPoint) + private function handleInit() { Context::set( RuntimeContextManager::class, new RuntimeContextManager(make(HubInterface::class)) ); return SentrySdk::getCurrentHub(); } - private function handleGetRuntimeContextManager(ProceedingJoinPoint $proceedingJoinPoint) + private function handleGetRuntimeContextManager() { return Context::getOrSet( RuntimeContextManager::class, fn () => new RuntimeContextManager(make(HubInterface::class)) ); }Also applies to: 63-63
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sentry/src/Aspect/SentrySdkAspect.php` at line 43, Both handleInit() and handleGetRuntimeContextManager() declare an unused ProceedingJoinPoint parameter causing static-analysis noise; remove the unused parameter from both method signatures (e.g., change "private function handleInit(ProceedingJoinPoint $proceedingJoinPoint)" and "private function handleGetRuntimeContextManager(ProceedingJoinPoint $proceedingJoinPoint)" to signatures without parameters), ensure there are no internal references to $proceedingJoinPoint, and update any callers or pointcut/advice mappings if they reference the method signature so the aspect wiring remains correct.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/sentry/src/Aspect/SentrySdkAspect.php`:
- Line 43: Both handleInit() and handleGetRuntimeContextManager() declare an
unused ProceedingJoinPoint parameter causing static-analysis noise; remove the
unused parameter from both method signatures (e.g., change "private function
handleInit(ProceedingJoinPoint $proceedingJoinPoint)" and "private function
handleGetRuntimeContextManager(ProceedingJoinPoint $proceedingJoinPoint)" to
signatures without parameters), ensure there are no internal references to
$proceedingJoinPoint, and update any callers or pointcut/advice mappings if they
reference the method signature so the aspect wiring remains correct.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
composer.jsonsrc/sentry/composer.jsonsrc/sentry/src/Aspect/SentrySdkAspect.phpsrc/sentry/src/ConfigProvider.php
…h() for improved event flushing
…mline configuration
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/sentry/src/Aspect/SentrySdkAspect.php`:
- Around line 54-55: The code is reading $arguments =
$proceedingJoinPoint->arguments['keys'] ?? []; and then accessing
$arguments['hub'] without checking existence which can throw an Undefined index
error; update the access to guard against missing 'hub' (e.g., retrieve with
$arguments['hub'] ?? null or use isset($arguments['hub']) before use) and add
handling when hub is null (early return, skip Sentry logic, or throw a clear
exception such as InvalidArgumentException) so the code using $arguments and
$proceedingJoinPoint does not assume the 'hub' key is present.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 81ff0dd8-c0f4-4a16-87d8-686bf7f879f9
📒 Files selected for processing (14)
src/sentry/class_map/SentrySdk.phpsrc/sentry/src/Aspect/CoroutineAspect.phpsrc/sentry/src/Aspect/SentrySdkAspect.phpsrc/sentry/src/ConfigProvider.phpsrc/sentry/src/Integration.phpsrc/sentry/src/Metrics/Listener/OnBeforeHandle.phpsrc/sentry/src/Metrics/Listener/OnCoroutineServerStart.phpsrc/sentry/src/Metrics/Listener/OnMetricFactoryReady.phpsrc/sentry/src/Metrics/Listener/OnWorkerStart.phpsrc/sentry/src/Metrics/Listener/PoolWatcher.phpsrc/sentry/src/Metrics/Listener/QueueWatcher.phpsrc/sentry/src/Metrics/Timer.phpsrc/sentry/src/Tracing/Aspect/CoroutineAspect.phpsrc/sentry/src/Tracing/Listener/EventHandleListener.php
💤 Files with no reviewable changes (1)
- src/sentry/class_map/SentrySdk.php
| $arguments = $proceedingJoinPoint->arguments['keys'] ?? []; | ||
| $hub = $arguments['hub']; |
There was a problem hiding this comment.
参数访问缺少防御性检查,可能导致运行时错误。
当 $arguments 数组中不存在 hub 键时,第 55 行会抛出 Undefined index 错误。建议添加空值检查或更明确的错误处理。
🛡️ 建议的修复方案
private function handleSetCurrentHub(ProceedingJoinPoint $proceedingJoinPoint)
{
$arguments = $proceedingJoinPoint->arguments['keys'] ?? [];
- $hub = $arguments['hub'];
+ $hub = $arguments['hub'] ?? throw new \InvalidArgumentException('Hub argument is required');
// `@phpstan-ignore-next-line`
Closure::bind(fn () => static::getRuntimeContextManager()->setCurrentHub($hub), null, SentrySdk::class)();
return $hub;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $arguments = $proceedingJoinPoint->arguments['keys'] ?? []; | |
| $hub = $arguments['hub']; | |
| private function handleSetCurrentHub(ProceedingJoinPoint $proceedingJoinPoint) | |
| { | |
| $arguments = $proceedingJoinPoint->arguments['keys'] ?? []; | |
| $hub = $arguments['hub'] ?? throw new \InvalidArgumentException('Hub argument is required'); | |
| // `@phpstan-ignore-next-line` | |
| Closure::bind(fn () => static::getRuntimeContextManager()->setCurrentHub($hub), null, SentrySdk::class)(); | |
| return $hub; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/sentry/src/Aspect/SentrySdkAspect.php` around lines 54 - 55, The code is
reading $arguments = $proceedingJoinPoint->arguments['keys'] ?? []; and then
accessing $arguments['hub'] without checking existence which can throw an
Undefined index error; update the access to guard against missing 'hub' (e.g.,
retrieve with $arguments['hub'] ?? null or use isset($arguments['hub']) before
use) and add handling when hub is null (early return, skip Sentry logic, or
throw a clear exception such as InvalidArgumentException) so the code using
$arguments and $proceedingJoinPoint does not assume the 'hub' key is present.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/sentry/src/Aspect/SentrySdkAspect.php`:
- Around line 55-63: handleSetCurrentHub currently uses Closure::bind to call
static::getRuntimeContextManager()->setCurrentHub($hub), which bypasses AOP and
returns the global cached RuntimeContextManager; replace that bypass with a
proper AOP-aware call: remove the Closure::bind call and instead let the
original join point execute (use $proceedingJoinPoint->proceed() or call
SentrySdk::getRuntimeContextManager() via the normal static call path so AOP can
intercept) and then call setCurrentHub on the resulting runtime context manager;
ensure you still return $hub and reference the existing symbols
handleSetCurrentHub, ProceedingJoinPoint::proceed,
SentrySdk::getRuntimeContextManager, and setCurrentHub.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 2843a136-bc87-4891-96d4-375506fa99ec
📒 Files selected for processing (1)
src/sentry/src/Aspect/SentrySdkAspect.php
Summary
SentrySdkAspectto make Sentry SDK methods coroutine-safe using Hyperf's Context APISentrySdk::init,::setCurrentHub, and::getRuntimeContextManagerRuntimeContextManagerstored in Hyperf's context for proper coroutine isolationTest plan
Summary by CodeRabbit
依赖更新
改进