Skip to content

Feat: CQRS dispatcher performance optimization with service cache and benchmark framework#341

Merged
GeWuYou merged 7 commits into
mainfrom
feat/cqrs-optimization
May 8, 2026
Merged

Feat: CQRS dispatcher performance optimization with service cache and benchmark framework#341
GeWuYou merged 7 commits into
mainfrom
feat/cqrs-optimization

Conversation

@GeWuYou
Copy link
Copy Markdown
Owner

@GeWuYou GeWuYou commented May 8, 2026

Summary by CodeRabbit

发行说明

  • 新功能

    • 新增流处理器生命周期基准套件,支持单例/瞬态对比并扩大了请求与流基准覆盖。
    • 引入生成式基准注册表机制,简化基准场景的注册与激活。
  • 性能优化

    • 优化分发器执行路径以减少异步开销。
    • 提升容器服务可见性检查性能,加入缓存稳定性改进。
  • 修复

    • 恢复请求调度的故障 ValueTask 语义,避免同步抛出,提高错误可观察性。
  • 文档

    • 更新代理技能与基准说明,明确将约80%上下文预算作为优先停止条件并完善停止/恢复指引。

GeWuYou added 5 commits May 8, 2026 11:38
- 优化 CqrsDispatcher.SendAsync 的 direct-return ValueTask 路径,移除 dispatcher 自身的异步状态机开销

- 引入 MicrosoftDiContainer 冻结后服务键索引,收敛 HasRegistration(Type) 的重复描述符扫描

- 更新 cqrs-rewrite active tracking 与 trace,记录 RP-104 的基线、验证结果与下一批建议
- 新增 handwritten generated request registry,并让默认 RequestBenchmarks 通过真实程序集注册路径接上 generated invoker provider

- 补齐 benchmark 最小宿主所需的 CQRS runtime、registrar 与 registration service 基础设施接线

- 更新 CQRS 迁移 tracking 与 trace,记录 RP-105 的 benchmark 结论和当前恢复点
- 新增 request pipeline benchmark 的 handwritten generated request registry,并通过真实程序集注册路径接上 generated invoker provider

- 更新 RequestPipelineBenchmarks 宿主接线与 benchmark README,统一默认 request 与 pipeline 场景的 generated-provider 口径

- 更新 CQRS 迁移 tracking 与 trace,记录 RP-106 的基线、验证结果与下一恢复点
- 新增默认 stream benchmark 的 handwritten generated registry,并通过真实程序集注册路径接上 generated stream invoker provider

- 更新 StreamingBenchmarks 宿主接线、README 与 RP-107 recovery 文档,统一 request、pipeline、stream 默认宿主口径

- 更新 gframework-boot 与 gframework-batch-boot 技能,改为以上下文预算接近约 80% 为默认优先停止信号
- 新增 stream handler 的 Singleton 和 Transient 生命周期 benchmark,并沿用 generated-provider 宿主接线

- 更新 CQRS benchmark README 与 active ai-plan 恢复点,记录 RP-108 的验证结果和下一步建议
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6376e7b4-131d-440d-a511-d7f43fb1dc07

📥 Commits

Reviewing files that changed from the base of the PR and between 9bd8c34 and 769d036.

📒 Files selected for processing (3)
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*[!.]*

📄 CodeRabbit inference engine (AGENTS.md)

For files with shebang lines, keep shebang as first line and place license header immediately after it

Files:

  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{md,mdx}: Keep code samples, package names, and command examples aligned with current repository state in documentation
When public page references XML docs or API coverage, convert evidence into reader-facing guidance: explain which types/namespaces/entry points readers should inspect and why
For integration-oriented features such as AI-First config system, documentation MUST cover: project directory layout/file conventions, required project/package wiring, minimal working example, migration/compatibility notes
When examples are rewritten, preserve only parts that remain true. Delete or replace speculative examples instead of lightly editing into another inaccurate form

Files:

  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
🔇 Additional comments (6)
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md (1)

5-28: 追踪记录准确,结构清晰

RP-110 阶段记录完整描述了 PR #341 latest-head review 的收尾工作,包括防御性 mock 补齐、trace 冗余删除等决策,验证步骤详实且符合标准 dotnet 工作流。之前 review 中指出的"本轮下一步"与"本轮权威验证"重复问题已在当前版本中解决。

ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md (5)

10-49: 追踪文档更新完整且准确

当前恢复点已正确更新至 RP-110,PR 锚点同步至 #341。"当前结论"部分详实记录了从 RP-103 到 RP-110 各阶段的关键决策与成果,包括:

  • RP-110 的防御性 mock 补齐与 trace 冗余删除
  • RP-109 的 benchmark 宿主定向激活与 faulted ValueTask 语义恢复
  • 历史各阶段的 benchmark 优化、generated provider 接入、生命周期矩阵补齐等

内容与 trace 文件保持一致,描述准确且便于后续恢复。


52-109: 活跃事实记录详实,benchmark 数据完整

"当前活跃事实"部分准确反映了最新状态:

  • baseline commit 与 trace 文件一致(4d6dbba6, 2026-05-08)
  • branch diff 统计清晰(14 files / 507 lines)
  • benchmark 结果具体且全面(request/stream steady-state、lifetime 矩阵、pipeline 数量等)
  • 关键技术决策已记录(HasRegistration fast-path、faulted ValueTask 语义、generated-provider 宿主接线)

数据呈现专业,便于性能回归对比与技术决策追溯。


111-128: 风险识别准确,为后续工作提供清晰指引

"当前风险"部分合理标识了现存技术债与优化方向:

  • stream 生命周期矩阵尚未对齐 Mediator compile-time lifetime 设计(line 118)
  • request steady-state 仍慢于 MediatR,需继续优化(line 120)
  • 内部 API 收口仍在进行,需避免混淆"对外替代完成"与"内部收口未完成"(line 121)

风险描述具体可操作,与"下一推荐步骤"形成良好呼应。


129-334: 权威验证记录全面,覆盖多轮 PR review

"最近权威验证"部分记录了从 RP-110 回溯至历史各阶段的完整验证结果:

  • 新增 RP-110 验证:build/test 通过,6/6 测试全过,license/diff 检查通过
  • 保留历史验证基线:RP-103 至 RP-109 的 benchmark 数据、PR review 确认
  • 验证命令标准且可重现:dotnet build/test、license-header.py、git diff --check

数据量大但组织清晰,为性能回归与质量把关提供可靠基线。


336-340: 下一步骤建议明确,优先级合理

"下一推荐步骤"提供清晰的后续方向:

  1. 在当前批次边界停止,避免上下文预算超限(line 338)
  2. 新 turn 从 RP-108 恢复,优先处理 notification publish 或高价值 dispatch 热点(line 339)
  3. 若需对齐 Mediator,先评估 compile-time lifetime 或 scoped host 基线(line 340)

建议具体可操作,与风险识别和活跃事实形成闭环。


📝 Walkthrough

Walkthrough

本 PR:为冻结 DI 容器添加服务类型索引,加速 HasRegistration;将 CqrsDispatcher.SendAsync 改为直接返回 ValueTask(同步异常映射为 faulted ValueTask);在基准主机工厂预注入 CQRS 基础设施并添加多个生成式请求/流注册表;引入 StreamLifetimeBenchmarks;更新若干基准的注册接入与缓存清理;添加/更新相关单元测试、AssemblyInfo 与 SKILL/迁移跟踪文档(上下文预算 ~80% 作为首要停止信号)。

Changes

DI 容器与调度器热路径优化

Layer / File(s) Summary
DI 容器服务索引
GFramework.Core/Ioc/MicrosoftDiContainer.cs
MicrosoftDiContainer 在 Freeze() 时构建 FrozenServiceTypeIndex,缓存精确类型与开放泛型定义;HasRegistration 优先查询索引;Clear()/Dispose() 清空索引。
调度器直接返回
GFramework.Cqrs/Internal/CqrsDispatcher.cs
SendAsync 从 async ValueTask 改为直接返回底层 RequestInvoker 或 pipeline.Invoke 的 ValueTask;同步异常被包装为 ValueTask.FromException(ex)。

基准测试基础设施重构

Layer / File(s) Summary
基准主机工厂基础设施
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
CreateFrozenGFrameworkContainer 在冻结前调用 RegisterCqrsInfrastructure,条件注册 ICqrsRuntime、legacy alias、ICqrsHandlerRegistrar 与 ICqrsRegistrationService,并提供 RegisterGeneratedBenchmarkRegistry。
生成式请求基准注册表
GFramework.Cqrs.Benchmarks/Messaging/Generated*RequestBenchmarkRegistry.cs
新增 GeneratedDefaultRequestBenchmarkRegistry 与 GeneratedRequestPipelineBenchmarkRegistry,定义静态请求描述符、Register/GetDescriptors/TryGetDescriptor 与静态 InvokeBenchmarkRequestHandler。
生成式流基准注册表
GFramework.Cqrs.Benchmarks/Messaging/Generated*StreamingBenchmarkRegistry.cs
新增 GeneratedDefaultStreamingBenchmarkRegistry(Register 时注册处理程序)和 GeneratedStreamLifetimeBenchmarkRegistry(Register 时仅验证/记录),均提供描述符与静态流调用入口。
基准容器接入与缓存清理
GFramework.Cqrs.Benchmarks/Messaging/*Benchmarks.cs
在 Setup 之前显式 ClearDispatcherCaches() 并在 Cleanup 中通过 try/finally 确保再次清除;多个基准切换为显式生成注册表或 RegisterCqrsHandlersFromAssembly 装配。
StreamLifetimeBenchmarks 新套件
GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
新增生命周期基准类,支持 HandlerLifetime(Singleton/Transient),GlobalSetup 构建按生命周期注册的容器/运行时并准备 MediatR 提供者;三个基准方法完整枚举流响应以测量端到端开销。

注册器与测试

Layer / File(s) Summary
单注册生成式注册表激活
GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
新增 RegisterGeneratedRegistry(...),激活并注册单个生成式注册表实例,包含参数校验与激活失败的错误处理。
单元测试与程序集可见性
GFramework.Cqrs.Tests/*, GFramework.Cqrs/Properties/AssemblyInfo.cs
新增测试验证生成式注册表只注册所选提供者;CqrsDispatcherContextValidationTests 增加 SendAsync 异步失败语义测试;添加 InternalsVisibleTo 指向测试与基准程序集。

文档与迁移跟踪

Layer / File(s) Summary
技能工作流文档
.agents/skills/gframework-batch-boot/SKILL.md, .agents/skills/gframework-boot/SKILL.md
gframework-batch-boot 将上下文预算安全(约 80%)提升为首要停止信号,增加批前估算与批后重算;gframework-boot 扩展复杂性分类与恢复启发式。
基准 README / 迁移跟踪
GFramework.Cqrs.Benchmarks/README.md, ai-plan/public/cqrs-rewrite/*.md
补充并对齐基准条目以反映已接入的手写生成式提供器/调用器提供程序;推进迁移跟踪至 RP-110(PR #341),记录验证步骤与结果。

Sequence Diagram(s)

sequenceDiagram
  participant BenchmarkFactory
  participant RegisterHelper
  participant DiContainer
  participant Logger
  BenchmarkFactory->>RegisterHelper: RegisterCqrsInfrastructure(container)
  RegisterHelper->>DiContainer: ensure ICqrsRuntime / registrar / registration-service
  alt missing generated registry
    RegisterHelper->>DiContainer: RegisterGeneratedBenchmarkRegistry<T>()
  end
  RegisterHelper->>Logger: log registrations
Loading

估算代码审查工作量

🎯 4 (Complex) | ⏱️ ~60 分钟

可能相关的 PRs

  • GeWuYou/GFramework#307: 生成式请求/流调用程序注册表与本 PR 的生成式注册表契约直接相关。
  • GeWuYou/GFramework#340: 修改相同的 DI 与 CQRS 热路径(MicrosoftDiContainer.HasRegistration 与 CqrsDispatcher)及基准主机/注册表配线。
  • GeWuYou/GFramework#302: 与生成式注册表、CqrsHandlerRegistry 生成器与反射回退相关的生成器/契约更改存在直接关联。
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the primary change: CQRS dispatcher performance optimization through service caching and benchmark framework establishment.
Docstring Coverage ✅ Passed Docstring coverage is 97.56% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cqrs-optimization

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2322 2322 0 0 0 0 38.6s    ↑1.6s

Test Results

passed 2322 passed

Details

tests 2322 tests
clock 38.6s ↑1.6s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1091
pull-request Feat/cqrs optimization link #341

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2229 0 1 4.7s

Fail Rate

Fail Rate 0.00%
Test 📝 Results 📊 Passed ✅ Failed ❌ Fail Rate (%) 📈
CreateStream_Should_Throw_When_Stream_Pipeline_Behavior_Context_Does_Not_Implement_IArchitectureContext 5 4 1 20.00    ↓5.00

build-and-test: Run #1091

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2322 2322 0 0 0 0 0 38.6s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 23 4.1s 4.7s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 38 1.6s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 38 2.2s 2.3s
Generates_Scene_Behavior_Boilerplate 38 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 38 1.1s 1.1s
Append_ShouldNotBlock 38 1.0s 1.0s
Context_Caching_Should_Improve_Performance 38 782ms 795ms
PendingCount_ShouldReflectQueuedEntries 38 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 38 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 38 401ms 402ms

± Comparison with run #1090 at b3ceb4e | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 38 runs.

Github Test Reporter by CTRF 💚

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
⚠️ CSHARP dotnet-format yes 1 no 6.33s
✅ REPOSITORY gitleaks yes no no 8.83s
✅ REPOSITORY trufflehog yes no no 6.95s

Detailed Issues

⚠️ CSHARP / dotnet-format - 1 error
Welcome to .NET 9.0!
---------------------
SDK Version: 9.0.114

----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate, run 'dotnet dev-certs https --trust'
Learn about HTTPS: https://aka.ms/dotnet-https

----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
Unhandled exception: System.Exception: Restore operation failed.
   at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
   at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
   at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)

See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 8, 2026

Greptile Summary

This PR optimises the CQRS dispatcher hot path and the HasRegistration lookup after container freeze, adds a benchmark suite for stream handler lifetimes, and introduces a targeted registry activation API to prevent cross-benchmark descriptor contamination (addressing a concern from the previous review cycle).

  • CqrsDispatcher.SendAsync de-async: async/await removed and synchronous errors now wrapped in ValueTask.FromException, preserving the original faulted-task semantics and avoiding the state-machine allocation on the happy path. Two new tests verify the behavioral contract.
  • FrozenServiceTypeIndex in MicrosoftDiContainer: After Freeze(), HasRegistration skips the linear ServiceCollection scan and hits a pre-built type index instead. The index logic (exact match + open-generic definition check) matches CanSatisfyServiceType exactly, so the semantics are preserved.
  • Targeted registry activation (CqrsHandlerRegistrar.RegisterGeneratedRegistry + BenchmarkHostFactory.RegisterGeneratedBenchmarkRegistry): Each benchmark now activates only the registry it owns rather than performing a full assembly scan, keeping the frozen service index and dispatcher descriptor baseline clean for measurement.

Confidence Score: 5/5

Safe to merge; all behavioural changes are backed by new tests and the core semantic contracts are preserved.

The dispatcher de-async change is correct and explicitly tested. The FrozenServiceTypeIndex replicates CanSatisfyServiceType semantics exactly. The benchmark infrastructure changes are additive. The only open concern is a benchmark-only registry whose Register is a no-op while still carrying an assembly attribute, which is a latent issue confined to test/benchmark code with no impact on production paths.

GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs — the no-op Register with an active assembly attribute creates an incomplete registry for any full assembly-scan caller.

Important Files Changed

Filename Overview
GFramework.Cqrs/Internal/CqrsDispatcher.cs De-asynced SendAsync hot path; synchronous exceptions now wrapped in ValueTask.FromException to preserve faulted-task semantics. Logic is correct and backed by two new tests.
GFramework.Core/Ioc/MicrosoftDiContainer.cs Adds FrozenServiceTypeIndex cache for HasRegistration after container freeze; semantics verified to be equivalent to HasRegistrationCore/CanSatisfyServiceType (exact + open-generic check).
GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs New RegisterGeneratedRegistry overload enables targeted single-registry activation without full assembly scan, solving the cross-registry contamination issue flagged in the previous review.
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs Adds RegisterCqrsInfrastructure and RegisterGeneratedBenchmarkRegistry helpers; INotificationPublisher resolved without null-check before being passed to CqrsRuntimeFactory.CreateRuntime on a fresh container.
GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs New benchmark comparing Singleton vs Transient stream handler dispatch; clean structure with proper setup/cleanup including dispatcher cache clearing.
GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs Intentional no-op Register() to let the benchmark control handler lifetime; the [assembly:CqrsHandlerRegistryAttribute] attribute makes this registry discoverable via full assembly scan, which would register the invoker descriptor without any handler — leading to dispatch failure if assembly scanning is used.
GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs Well-structured generated registry for default request benchmarks; handler registered as singleton, descriptor exposed correctly.
GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs Two new tests verify that SendAsync returns a faulted ValueTask (not a synchronous throw) when context preparation fails or when a handler is missing — correctly validates the de-async behavioral contract.
GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs New test confirms RegisterGeneratedRegistry activates only the selected provider and does not leak other registries from the same assembly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["SendAsync(context, request, ct)"] --> B{try block}
    B --> C[Validate context & request]
    C --> D[GetRequestDispatchBinding]
    D --> E[container.Get handler]
    E --> F{handler found?}
    F -- No --> G["throw InvalidOperationException"]
    F -- Yes --> H[PrepareHandler]
    H --> I{HasRegistration BehaviorType?}
    I -- No --> J["return RequestInvoker(...)"]
    I -- Yes --> K[GetAll behaviors, PrepareHandler each]
    K --> L["return PipelineExecutor(...)"]
    G --> M["catch Exception"]
    C --> M
    D --> M
    M --> N["return ValueTask.FromException(ex)"]

    subgraph HasRegistration ["HasRegistration - MicrosoftDiContainer"]
        R1{frozen?} -- Yes --> R2["FrozenServiceTypeIndex.Contains exact OR open-generic"]
        R1 -- No --> R3["HasRegistrationCore linear scan CanSatisfyServiceType"]
    end

    I --> R1
Loading
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs:56-66
**No-op `Register` paired with active assembly attribute creates an incomplete registry on full scan**

`Register` deliberately skips writing the handler so the benchmark can control lifetime explicitly — that is fine for the `RegisterGeneratedBenchmarkRegistry` path. However, the `[assembly: CqrsHandlerRegistryAttribute(typeof(GeneratedStreamLifetimeBenchmarkRegistry))]` attribute at the top of the file makes this registry discoverable by `RegisterCqrsHandlersFromAssembly`. On that path the invoker descriptor is registered but the handler is not, so any subsequent `CreateStream` / `SendAsync` dispatch would throw `InvalidOperationException("No CQRS request handler registered for …")`. Removing the assembly attribute — or adding a default-singleton fallback inside `Register` that can be overridden by the caller — would close the gap.

### Issue 2 of 3
GFramework.Core/Ioc/MicrosoftDiContainer.cs:1198-1201
**`FrozenServiceTypeIndex` stores mutable `HashSet<Type>` after construction**

The two `HashSet<T>` fields are only ever read after the constructor returns, but a mutable `HashSet` still holds extra capacity metadata and allows accidental mutation from within the same class. `System.Collections.Frozen.FrozenSet<T>` (available since .NET 8) is specifically designed for this pattern — built once, read many — and is typically faster for `Contains` lookups on the hot path that this index is meant to optimise.

```suggestion
    private sealed class FrozenServiceTypeIndex(FrozenSet<Type> exactServiceTypes, FrozenSet<Type> openGenericServiceTypes)
    {
        private readonly FrozenSet<Type> _exactServiceTypes = exactServiceTypes;
        private readonly FrozenSet<Type> _openGenericServiceTypes = openGenericServiceTypes;
```

### Issue 3 of 3
GFramework.Core/Ioc/MicrosoftDiContainer.cs:1212-1226
The two intermediate `HashSet<Type>` collections should be converted to `FrozenSet<Type>` before being passed to the constructor, so that the `Create` factory and the container fields are consistent.

```suggestion
            var exactServiceTypes = new HashSet<Type>();
            var openGenericServiceTypes = new HashSet<Type>();

            foreach (var descriptor in descriptors)
            {
                var serviceType = descriptor.ServiceType;
                exactServiceTypes.Add(serviceType);

                if (serviceType.IsGenericTypeDefinition)
                {
                    openGenericServiceTypes.Add(serviceType);
                }
            }

            return new FrozenServiceTypeIndex(exactServiceTypes.ToFrozenSet(), openGenericServiceTypes.ToFrozenSet());
```

Reviews (3): Last reviewed commit: "fix(cqrs): 收口PR341剩余review尾项" | Re-trigger Greptile

Comment thread GFramework.Cqrs/Internal/CqrsDispatcher.cs
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a 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)
GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs (1)

99-101: 💤 Low value

建议补充注释说明为何重新创建 runtime 实例

RegisterCqrsInfrastructure(由 CreateFrozenGFrameworkContainer 调用)已向容器内注册了一个 ICqrsRuntime;这里又在容器冻结后创建了第二个实例并赋给 _runtime。两者共享同一底层容器,功能上不冲突,但目的不同:容器内的 runtime 是为了让 RegisterCqrsHandlersFromAssembly(...) 能在配置阶段解析到 runtime 服务,而 _runtime 使用了包含 lifetime 参数的专属 logger 名称以区分不同生命周期矩阵的日志。

若缺少这一说明,后续维护者可能会尝试改写为 container.GetRequired<ICqrsRuntime>(),导致 logger 名称退化为 "CqrsDispatcher",使跨 lifetime 组的 benchmark 日志失去区分。

📝 建议补充注释
+        // 容器内已由 RegisterCqrsInfrastructure 注册了一个 ICqrsRuntime(logger 名为 "CqrsDispatcher"),
+        // 此处额外创建一个携带 benchmark-specific logger 名称的独立实例,用于区分 Singleton / Transient 两档的运行日志。
+        // 两个实例共享同一冻结容器,handler 解析路径完全一致,因此不存在功能上的干扰。
         _runtime = GFramework.Cqrs.CqrsRuntimeFactory.CreateRuntime(
             _container,
             LoggerFactoryResolver.Provider.CreateLogger(nameof(StreamLifetimeBenchmarks) + "." + Lifetime));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs` around
lines 99 - 101, 在这段给 _runtime
赋值(GFramework.Cqrs.CqrsRuntimeFactory.CreateRuntime(...))的代码附近补充注释,说明为何在容器冻结后还要重新创建一个
ICqrsRuntime 实例:RegisterCqrsInfrastructure(由 CreateFrozenGFrameworkContainer
调用)已经向容器注册了一个 runtime 用于 RegisterCqrsHandlersFromAssembly 在配置阶段解析,但这里单独创建的
_runtime 使用包含 Lifetime 的专属 logger 名称以在不同生命周期矩阵的基准测试日志中保持可区分性;并警告不要替换为
container.GetRequired<ICqrsRuntime>()(否则 logger 名称会退化为 "CqrsDispatcher" 并丢失区分)。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/gframework-batch-boot/SKILL.md:
- Line 150: 修复 MD005 缩进错误:将文件 SKILL.md 中子项 "recompute the primary stop-condition
metric" 的缩进减少 1 个空格,使其与同级列表项对齐(与其他兄弟项采用相同的缩进级别),保存后重新运行 markdownlint
验证无需改动其他文本或内容。

In `@GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs`:
- Around line 60-66: Replace the direct casts to LegacyICqrsRuntime in
BenchmarkHostFactory with defensive type checks: instead of
(LegacyICqrsRuntime)runtime, verify runtime is LegacyICqrsRuntime using the "is
not" / pattern-match form and throw an InvalidOperationException containing both
the expected and actual runtime types if the check fails; register the matched
variable when successful. Do the same for the
container.GetRequired<ICqrsRuntime>() path: obtain the ICqrsRuntime, check it is
a LegacyICqrsRuntime before registering, and throw an InvalidOperationException
with full type info on mismatch; follow the same pattern used in
CqrsTestRuntime.cs (lines 102–111) for consistency.

---

Nitpick comments:
In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs`:
- Around line 99-101: 在这段给 _runtime
赋值(GFramework.Cqrs.CqrsRuntimeFactory.CreateRuntime(...))的代码附近补充注释,说明为何在容器冻结后还要重新创建一个
ICqrsRuntime 实例:RegisterCqrsInfrastructure(由 CreateFrozenGFrameworkContainer
调用)已经向容器注册了一个 runtime 用于 RegisterCqrsHandlersFromAssembly 在配置阶段解析,但这里单独创建的
_runtime 使用包含 Lifetime 的专属 logger 名称以在不同生命周期矩阵的基准测试日志中保持可区分性;并警告不要替换为
container.GetRequired<ICqrsRuntime>()(否则 logger 名称会退化为 "CqrsDispatcher" 并丢失区分)。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f4b7a5ab-cd9c-4df3-82ba-d6ef4707bd19

📥 Commits

Reviewing files that changed from the base of the PR and between 4d6dbba and 39ac61c.

📒 Files selected for processing (16)
  • .agents/skills/gframework-batch-boot/SKILL.md
  • .agents/skills/gframework-boot/SKILL.md
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/README.md
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (C#)
  • GitHub Check: Code Quality & Security
  • GitHub Check: Build and Test
🧰 Additional context used
📓 Path-based instructions (8)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) in C#
XML documentation MUST use <summary>, <param>, <returns>, <exception>, and <remarks> where applicable, and explain intent, contract, and usage constraints instead of restating syntax
If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why abstraction exists, and when to use instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Do not rely on implicit imports. Declare every required using explicitly in C#
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C#
Use namespace pattern GFramework.{Module}.{Feature} with PascalCase segments in C#
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, Interfaces use I prefix, Parameters and locals use camelCase, Private fields use _camelCase
Use Allman braces style for C#
Keep using directives at the top of the file and sort them consistently in C#
Prefer one primary type per file unless surrounding project already uses different local pattern
Prefer explicit, readable code over clever shorthand in framework internals
M...

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
**/*[!.]*

📄 CodeRabbit inference engine (AGENTS.md)

For files with shebang lines, keep shebang as first line and place license header immediately after it

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/README.md
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{cs,ts,tsx,js,jsx,py,sh}: All generated or modified code MUST include clear and meaningful comments where required by documentation rules
Comments MUST NOT be trivial, redundant, or misleading. Prefer explaining why and when, not just what. Code should remain understandable without requiring external context
Avoid obvious comments such as // increment i

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{cs,ts,tsx,js,jsx,py}: Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds/compatibility constraints/edge cases, and registration order/lifecycle sequencing/generated code assumptions
Methods with non-trivial logic MUST document core idea, key decisions, and edge case handling
Separate logical blocks with blank lines when it improves readability
Unless there is clear and documented reason to keep file large, keep single source file under roughly 800-1000 lines
Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation, or process boundaries
Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation or allow-listing
Avoid logging secrets, tokens, credentials, or machine-specific sensitive data
Prefer least-privilege behavior for file, process, and environment access

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
**/*.{csproj,cs}

📄 CodeRabbit inference engine (AGENTS.md)

Framework runtime, abstractions, and meta-package projects MUST NOT reference *.SourceGenerators* projects or packages, and MUST NOT use source-generator attributes

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml,csproj,props,targets}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation. Do not use tabs

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml}

📄 CodeRabbit inference engine (AGENTS.md)

Keep line length readable. Around 120 characters is preferred upper bound

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{md,mdx}: Keep code samples, package names, and command examples aligned with current repository state in documentation
When public page references XML docs or API coverage, convert evidence into reader-facing guidance: explain which types/namespaces/entry points readers should inspect and why
For integration-oriented features such as AI-First config system, documentation MUST cover: project directory layout/file conventions, required project/package wiring, minimal working example, migration/compatibility notes
When examples are rewritten, preserve only parts that remain true. Delete or replace speculative examples instead of lightly editing into another inaccurate form

Files:

  • GFramework.Cqrs.Benchmarks/README.md
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
🪛 LanguageTool
.agents/skills/gframework-boot/SKILL.md

[style] ~76-~76: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...re asking the user for clarification. - If the current turn already carries heavy ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.22.1)
.agents/skills/gframework-batch-boot/SKILL.md

[warning] 150-150: Inconsistent indentation for list items at the same level
Expected: 3; Actual: 4

(MD005, list-indent)

🔇 Additional comments (10)
GFramework.Core/Ioc/MicrosoftDiContainer.cs (1)

1053-1056: 冻结索引优化实现完整且一致。

冻结后走索引查询、在 Clear/Dispose 里回收索引,和当前锁模型、生命周期语义保持一致,改动方向很好。

Also applies to: 1181-1182, 1191-1242

GFramework.Cqrs/Internal/CqrsDispatcher.cs (1)

108-108: 请求分发热路径精简得当。

这里直接返回 ValueTask<TResponse>,在保持行为不变的前提下去掉了额外状态机开销,适合 benchmark/运行时热点路径。

Also applies to: 125-126, 135-136

GFramework.Cqrs.Benchmarks/README.md (1)

18-18: 基准矩阵文案对齐良好。

这些描述与当前 benchmark 的生成器/注册路径表述一致,可读性更好。

Also applies to: 21-22, 24-24, 34-34

GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs (1)

64-64: 缓存清理时机和兜底路径处理得很好。

Setup 预清理 + Cleanuptry/finally 组合能有效避免跨轮 benchmark 污染。

Also applies to: 69-70, 94-101

GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs (1)

72-73: pipeline 基准的处理器注册入口统一得很好。

这里与其它 benchmark 的程序集注册路径保持一致,后续维护会更简单。

GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs (1)

21-22: 流式基准的注册与缓存隔离改动是正确的。

程序集 registry 绑定与 setup/cleanup 缓存清理形成闭环,有助于减少跨轮次干扰。

Also applies to: 65-65, 70-70, 92-99

GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestPipelineBenchmarkRegistry.cs (1)

1-100: LGTM!

手写 generated registry 模式实现一致;使用 nameof 做反射方法名查找、?? throw 防止静默失效,以及通过静态描述符列表缓存加速类型查找,都是正确做法。

GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultStreamingBenchmarkRegistry.cs (1)

1-96: LGTM!

stream invoker 返回 object 与框架的 invoker 合同一致(运行时负责向 IAsyncEnumerable<TResponse> 转型),nameof + ?? throw 的方法查找保护与其他 registry 保持对称。

GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs (1)

1-110: LGTM!

Register() 刻意不写入 handler 生命周期(只记录 debug 日志)是正确设计:让 benchmark 主体通过 RegisterGFrameworkHandler(container, Lifetime) 显式控制 Singleton / Transient 变量,确保生命周期矩阵的比较变量保持单一。该意图在 <remarks> 中已清晰说明。

GFramework.Cqrs.Benchmarks/Messaging/GeneratedDefaultRequestBenchmarkRegistry.cs (1)

1-100: LGTM!

GeneratedRequestPipelineBenchmarkRegistry 实现完全对称;ValueTask<BenchmarkResponse> 返回类型、nameof 反射查找、静态描述符缓存均正确,Register() 按单例注册保持与原 steady-state 宿主一致的生命周期语义。

Comment thread .agents/skills/gframework-batch-boot/SKILL.md Outdated
Comment thread GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
- 修复 benchmark 宿主误激活同程序集其他 generated registry 的接线路径,收窄服务索引与 descriptor 基线

- 恢复 CqrsDispatcher.SendAsync 的 faulted ValueTask 失败语义,并补充相关回归测试

- 补充 legacy runtime alias 的防守式类型检查、stream lifetime 注释与 cqrs-rewrite 恢复文档验证记录
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2325    ↑3 2325    ↑3 0 0 0 0 37.9s    ↓781ms

Test Results

passed 2325 passed ↑3

Details

tests 2325 tests ↑3
clock 37.9s ↓781ms
tool nunit
build CI - Build & Test arrow-right build-and-test link #1092
pull-request Feat/cqrs optimization link #341

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2231 0 1 4.7s

Fail Rate

Fail Rate 0.00%
Test 📝 Results 📊 Passed ✅ Failed ❌ Fail Rate (%) 📈
CreateStream_Should_Throw_When_Stream_Pipeline_Behavior_Context_Does_Not_Implement_IArchitectureContext 6 5 1 16.67    ↓3.33

build-and-test: Run #1092

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2325 2325 0 0 0 0 0 37.9s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 24 4.1s 4.7s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 39 1.6s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 39 2.2s 2.3s
Generates_Scene_Behavior_Boilerplate 39 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 39 1.1s 1.1s
Append_ShouldNotBlock 39 1.0s 1.0s
Context_Caching_Should_Improve_Performance 39 782ms 795ms
PendingCount_ShouldReflectQueuedEntries 39 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 39 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 39 401ms 402ms

± Comparison with run #1091 at 5fac56a | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 39 runs.

Github Test Reporter by CTRF 💚

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs (1)

78-95: ⚡ Quick win

建议为缺失 handler 测试补充 pipeline behavior 的 mock 配置,减少对 dispatch 内部顺序的隐式依赖

当前测试使用 MockBehavior.Strict 但只配置了 Get 返回 null,未配置 HasRegistration(IPipelineBehavior<...>)GetAll(IPipelineBehavior<...>)。测试能通过,说明 dispatcher 当前会在检查 pipeline 之前先判断 handler 是否为 null;一旦内部执行顺序调整,strict mock 会抛出 MockException 而非预期的 InvalidOperationException,导致测试失败时的错误信息与实际意图不符,难以定位。

♻️ 建议补充防御性 mock 配置
 var runtime = CreateRuntime(
     container =>
     {
         container
             .Setup(currentContainer => currentContainer.Get(typeof(IRequestHandler<ContextAwareRequest, int>)))
             .Returns((object?)null);
+        container
+            .Setup(currentContainer => currentContainer.HasRegistration(typeof(IPipelineBehavior<ContextAwareRequest, int>)))
+            .Returns(false);
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs` around
lines 78 - 95, Test relies on MockBehavior.Strict but only stubs Get for
IRequestHandler, making it brittle to internal ordering; update the mock setup
in the CreateRuntime container configuration used by
SendAsync(ContextAwareRequest) to also handle pipeline checks by configuring
HasRegistration(typeof(IPipelineBehavior<ContextAwareRequest,int>)) to return
false (or true as appropriate) and
GetAll(typeof(IPipelineBehavior<ContextAwareRequest,int>)) to return an empty
enumerable, so the strict mock won't throw if dispatcher queries pipeline
registration/get-all before checking the handler and the test continues to
assert the InvalidOperationException when handler is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md`:
- Around line 32-33: The "本轮下一步" section duplicates the already completed
"本轮权威验证" steps (Release build / targeted tests / license header check / `git
diff --check`), causing redundancy; locate the "本轮下一步" heading and either (a)
replace its content with true post-merge follow-ups (e.g., monitoring, rollout,
further integrations, follow-up issues) or (b) remove the duplicated lines
entirely so only "本轮权威验证" remains; target the text blocks containing the
headings "本轮下一步" and "本轮权威验证" to make this edit.

---

Nitpick comments:
In `@GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs`:
- Around line 78-95: Test relies on MockBehavior.Strict but only stubs Get for
IRequestHandler, making it brittle to internal ordering; update the mock setup
in the CreateRuntime container configuration used by
SendAsync(ContextAwareRequest) to also handle pipeline checks by configuring
HasRegistration(typeof(IPipelineBehavior<ContextAwareRequest,int>)) to return
false (or true as appropriate) and
GetAll(typeof(IPipelineBehavior<ContextAwareRequest,int>)) to return an empty
enumerable, so the strict mock won't throw if dispatcher queries pipeline
registration/get-all before checking the handler and the test continues to
assert the InvalidOperationException when handler is missing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d647a06c-3aff-496e-a699-5c5fe100198a

📥 Commits

Reviewing files that changed from the base of the PR and between 39ac61c and 9bd8c34.

📒 Files selected for processing (15)
  • .agents/skills/gframework-batch-boot/SKILL.md
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
🚧 Files skipped from review as they are similar to previous changes (7)
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs/Internal/CqrsDispatcher.cs
  • .agents/skills/gframework-batch-boot/SKILL.md
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) in C#
XML documentation MUST use <summary>, <param>, <returns>, <exception>, and <remarks> where applicable, and explain intent, contract, and usage constraints instead of restating syntax
If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why abstraction exists, and when to use instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Do not rely on implicit imports. Declare every required using explicitly in C#
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C#
Use namespace pattern GFramework.{Module}.{Feature} with PascalCase segments in C#
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, Interfaces use I prefix, Parameters and locals use camelCase, Private fields use _camelCase
Use Allman braces style for C#
Keep using directives at the top of the file and sort them consistently in C#
Prefer one primary type per file unless surrounding project already uses different local pattern
Prefer explicit, readable code over clever shorthand in framework internals
M...

Files:

  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
**/*[!.]*

📄 CodeRabbit inference engine (AGENTS.md)

For files with shebang lines, keep shebang as first line and place license header immediately after it

Files:

  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
**/*.{cs,ts,tsx,js,jsx,py,sh}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{cs,ts,tsx,js,jsx,py,sh}: All generated or modified code MUST include clear and meaningful comments where required by documentation rules
Comments MUST NOT be trivial, redundant, or misleading. Prefer explaining why and when, not just what. Code should remain understandable without requiring external context
Avoid obvious comments such as // increment i

Files:

  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
**/*.{cs,ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{cs,ts,tsx,js,jsx,py}: Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds/compatibility constraints/edge cases, and registration order/lifecycle sequencing/generated code assumptions
Methods with non-trivial logic MUST document core idea, key decisions, and edge case handling
Separate logical blocks with blank lines when it improves readability
Unless there is clear and documented reason to keep file large, keep single source file under roughly 800-1000 lines
Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation, or process boundaries
Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation or allow-listing
Avoid logging secrets, tokens, credentials, or machine-specific sensitive data
Prefer least-privilege behavior for file, process, and environment access

Files:

  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
**/*.{csproj,cs}

📄 CodeRabbit inference engine (AGENTS.md)

Framework runtime, abstractions, and meta-package projects MUST NOT reference *.SourceGenerators* projects or packages, and MUST NOT use source-generator attributes

Files:

  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml,csproj,props,targets}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation. Do not use tabs

Files:

  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml}

📄 CodeRabbit inference engine (AGENTS.md)

Keep line length readable. Around 120 characters is preferred upper bound

Files:

  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
**/Cqrs/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

Use CQRS (Command Query Responsibility Segregation) pattern with the Cqrs naming entry point instead of the historical Mediator alias

Files:

  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{md,mdx}: Keep code samples, package names, and command examples aligned with current repository state in documentation
When public page references XML docs or API coverage, convert evidence into reader-facing guidance: explain which types/namespaces/entry points readers should inspect and why
For integration-oriented features such as AI-First config system, documentation MUST cover: project directory layout/file conventions, required project/package wiring, minimal working example, migration/compatibility notes
When examples are rewritten, preserve only parts that remain true. Delete or replace speculative examples instead of lightly editing into another inaccurate form

Files:

  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.Cqrs/Properties/AssemblyInfo.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs
  • GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs
🔇 Additional comments (6)
GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs (1)

82-99: 新增 RegisterGeneratedRegistry 入口实现简洁,LGTM

null 校验完备、IL 工厂缓存路径与现有 TryCreateGeneratedRegistry 一致、collection expression [registry] 在 net8.0+ 目标框架下合法。TryCreateGeneratedRegistry 在各失败模式下已通过 logger.Warn 输出具体原因,最外层 InvalidOperationException 作为调用侧的编程时错误信号,设计合理。

GFramework.Cqrs/Properties/AssemblyInfo.cs (1)

6-7: InternalsVisibleTo 声明正确,LGTM

两个友元程序集声明与 PR 中 benchmark/测试对 CqrsHandlerRegistrar 内部成员的访问需求一致。程序集当前无强签名,因此无需附带公钥。若后续引入强签名,需同步补充 PublicKey=... 参数。

GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs (1)

84-90: 定向 registry 接线正确,LGTM

从全程序集扫描切到 RegisterGeneratedBenchmarkRegistry<GeneratedStreamInvokerBenchmarkRegistry> 的改动与 PR 目标一致,确保基准容器不会意外激活同程序集内的其他 generated registry。

GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs (1)

84-90: StreamInvokerBenchmarks 的模式保持对称,LGTM

GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs (1)

107-127: 隔离性验证测试设计完整,LGTM

Assert.Multiple 同时断言 request provider 存在且 stream provider 为空,精确覆盖了 RegisterGeneratedRegistry 的"仅激活指定 registry、不旁触其他 registry"语义。[NonParallelizable] 已在类级别声明,静态缓存的清理与恢复逻辑由现有 SetUp/TearDown 统一处理。

GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs (1)

92-100: Cleanuptry/finally 模式正确,LGTM

即使 DisposeAll 抛出,ClearDispatcherCaches 仍会执行,避免 dispatcher 静态缓存残留污染后续 benchmark 轮次。与其他 benchmark 文件(如 RequestInvokerBenchmarks)的清理模式对称。

Comment thread ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md Outdated
- 修复 request faulted ValueTask 回归测试对 pipeline 探测顺序的隐式依赖,补齐 HasRegistration 与 GetAll 的防御性 mock

- 更新 cqrs-rewrite tracking 与 trace,记录 PR #341 latest-head review 的 stale thread 复核结论与本轮验证结果
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2325 2325 0 0 0 0 38.3s    ↑401ms

Test Results

passed 2325 passed

Details

tests 2325 tests
clock 38.3s ↑401ms
tool nunit
build CI - Build & Test arrow-right build-and-test link #1093
pull-request Feat/cqrs optimization link #341

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2234 0 1 4.7s

Fail Rate

Fail Rate 0.00%
Test 📝 Results 📊 Passed ✅ Failed ❌ Fail Rate (%) 📈
CreateStream_Should_Throw_When_Stream_Pipeline_Behavior_Context_Does_Not_Implement_IArchitectureContext 7 6 1 14.29    ↓2.38

build-and-test: Run #1093

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2325 2325 0 0 0 0 0 38.3s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 25 4.1s 4.7s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 40 1.6s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 40 2.2s 2.3s
Generates_Scene_Behavior_Boilerplate 40 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 40 1.1s 1.1s
Append_ShouldNotBlock 40 1.0s 1.0s
Context_Caching_Should_Improve_Performance 40 782ms 794ms
PendingCount_ShouldReflectQueuedEntries 40 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 40 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 40 401ms 402ms

± Comparison with run #1092 at fb96d5d | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 40 runs.

Github Test Reporter by CTRF 💚

@GeWuYou GeWuYou enabled auto-merge May 8, 2026 07:32
@GeWuYou GeWuYou changed the title Feat/cqrs optimization Feat: CQRS dispatcher performance optimization with service cache and benchmark framework May 8, 2026
@GeWuYou
Copy link
Copy Markdown
Owner Author

GeWuYou commented May 8, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@GeWuYou GeWuYou merged commit 7ca21af into main May 8, 2026
7 checks passed
@GeWuYou GeWuYou deleted the feat/cqrs-optimization branch May 8, 2026 08:12
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.

1 participant