Skip to content

Test/Add comprehensive CQRS benchmarking suite with reflection and generated invoker paths#326

Merged
GeWuYou merged 10 commits into
mainfrom
feat/cqrs-optimization
May 6, 2026
Merged

Test/Add comprehensive CQRS benchmarking suite with reflection and generated invoker paths#326
GeWuYou merged 10 commits into
mainfrom
feat/cqrs-optimization

Conversation

@GeWuYou
Copy link
Copy Markdown
Owner

@GeWuYou GeWuYou commented May 6, 2026

Summary by CodeRabbit

发布说明

  • 新功能

    • 新增独立性能基准项目并提供可运行的基准入口,支持多种调度路径对比。
  • 测试

    • 添加完整基准套件:请求、通知、流式、管道、启动与调用器比较等场景。
    • 新增回归测试以确保生成注册器在混合实现下的顺序稳定性。
  • 文档

    • 增加基准模块中文 README 与迁移追踪文档。
  • Chores

    • 将基准项目从主构建/打包中排除并添加 CI 基准工作流。

GeWuYou added 6 commits May 6, 2026 08:57
- 新增独立的 GFramework.Cqrs.Benchmarks 项目并引入 request、notification 对比场景

- 补充 request 与 stream invoker provider 的 mixed direct/reflected 顺序回归测试

- 更新 solution、meta-package 排除规则与 CQRS ai-plan 恢复点
- 新增 StreamingBenchmarks 并对齐 baseline、GFramework.Cqrs 与 MediatR 的完整枚举对照

- 更新 benchmark README 与 CQRS ai-plan 恢复点,记录 stream 场景落地
- 新增 request pipeline 0/1/4 数量矩阵基准并保持 GFramework.Cqrs 与 MediatR 对照

- 更新 benchmark README 说明当前场景覆盖与后续扩展方向

- 补充 cqrs-rewrite 跟踪与 trace 的 RP-086 恢复点和验证记录
- 新增 request initialization 与 cold-start 基准并对齐当前 runtime 启动口径

- 通过清理 dispatcher 静态缓存隔离 GFramework.Cqrs 首次分发测量结果

- 更新 benchmark README 与 cqrs-rewrite RP-087 跟踪记录
- 新增 request reflection 与 generated invoker provider 的 steady-state 对照基准

- 引入 handwritten generated registry/provider 以走通真实 registrar 与 dispatcher 预热链路

- 更新 benchmark README 与 cqrs-rewrite RP-088 跟踪记录
- 新增 stream generated invoker benchmark 与手写 registry,对照 reflection runtime、generated runtime 和 MediatR 的完整枚举开销

- 更新 benchmark README,补充 generated stream invoker provider 的场景说明与后续扩展方向

- 更新 cqrs-rewrite 跟踪与 trace,记录 RP-089 的基线、验证结果和下一批建议
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

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: 56eba79f-8fc2-410a-8c83-5cea8a27c397

📥 Commits

Reviewing files that changed from the base of the PR and between 2cb6216 and 6d619b9.

📒 Files selected for processing (6)
  • .github/workflows/benchmark.yml
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.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)
  • .github/workflows/benchmark.yml
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (8)
**/*[!.]*

📄 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/todos/cqrs-rewrite-migration-tracking.md
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
**/*.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/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
🧠 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/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
🪛 LanguageTool
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md

[grammar] ~498-~498: Use a hyphen to join words.
Context: ...registration / service lifetime 或 stream generated provider ### 阶段:stream invoke...

(QB_NEW_EN_HYPHEN)


[uncategorized] ~539-~539: The official name of this software platform is spelled with a capital “H”.
Context: ...ark workflow(CQRS-REWRITE-RP-089) - 新增 .github/workflows/benchmark.yml,提供仅 `workflow_...

(GITHUB)


[grammar] ~539-~539: Ensure spelling is correct
Context: ...提供仅 workflow_dispatch 触发的 benchmark 入口 - workflow 默认只执行 GFramework.Cqrs.Benchmarks 的 Re...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (8)
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md (2)

3-69: ✅ RP-090 文档结构清晰,修复记录完整

本节完整记录了 benchmark 对照宿主收敛与 cold-start 恢复的全过程,关键改进点明确:

  • 统一通过 BenchmarkHostFactory 构建最小宿主
  • GFramework 侧显式 Freeze() 容器
  • MediatR 侧限制扫描范围
  • ColdStart_GFrameworkCqrs 已恢复出有效结果

验证命令与结果均已对齐当前仓库状态,符合编码指南要求。


283-542: 📋 RP-083 ~ RP-089 历史记录保留合理

该段落按时间顺序记录了从 mixed invoker provider 排序回归到 stream invoker benchmark 的完整演进过程。需要注意的是,Line 535 记录的 ColdStart_GFrameworkCqrs 失败是当时(RP-089)的真实状态,该问题已在后续的 RP-090(文档顶部)中得到解决。

这种保留历史失败记录的做法符合 trace 文档的设计目的,读者应优先参考文档顶部的 RP-090 获取最新权威状态。

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

10-29: ✅ 恢复点信息更新准确,历史演进清晰

当前恢复点 RP-090 与 PR #326 锚点已正确更新,RP-083 至 RP-090 的结论汇总完整记录了 benchmark 基础设施的引入与优化过程。各阶段里程碑表述清晰,符合文档规范。


33-58: ✅ 当前活跃事实与权威验证已保持一致

Line 36 描述的 ColdStart_GFrameworkCqrs 恢复状态与 Lines 50-52 的验证结果完全对齐(已产出有效结果,本地输出约 220-292 us)。过往 review 中提到的矛盾问题已得到妥善解决,当前文档准确反映了仓库最新状态。

As per coding guidelines, 命令示例与验证结果均与当前仓库状态保持同步。


67-69: ✅ 下一步骤聚焦明确,优先级合理

三条推荐步骤清晰聚焦于:

  1. PR review 消化确认
  2. 基准语义反馈分类
  3. CI benchmark 手动复核策略

步骤优先级合理,与当前 PR #326 的收尾阶段相匹配。

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

61-108: 基准隔离和生命周期对齐处理得不错。

这里同时做了 dispatcher 缓存清理,并把 MediatR 对照组保持为 Transient,能更好地把结果聚焦在 invoker 路径本身,而不是宿主残留状态或实例复用差异。

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

61-108: 这组 stream benchmark 的基线控制比较稳。

缓存清理、Transient 生命周期对齐,以及三条路径共享同一枚举形状,基本把对比面收敛到了 stream invoker 本身。

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

170-185: 原始评论的关注点经验证不成立。RegisterCqrsPipelineBehavior<TBehavior>() 在两种情况下都使用 AddSingleton 注册行为(开放泛型和已闭合泛型均同),与基准测试中 MediatR 侧的 AddSingleton<IPipelineBehavior<BenchmarkRequest, BenchmarkResponse>, BenchmarkPipelineBehaviorN>() 生命周期一致。两侧均为单例,benchmark 在实例复用方面是公平的,不存在生命周期错配问题。


📝 Walkthrough

Walkthrough

新增独立的 GFramework.Cqrs.Benchmarks 项目,包含 BenchmarkDotNet 基准套件、基准运行入口、DI/宿主与 MediatR 构建辅助、生成/反射调用器注册表、缓存清理工具、多个请求/通知/流/管道/启动基准实现、相关源生成器稳定性测试与 CI 基准工作流。

Changes

基准测试与性能对标基础设施

Layer / File(s) Summary
项目元与解决方案集成
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj, GFramework.sln, GFramework.csproj
新增独立基准项目(net10.0)、将其加入解决方案并在主项目中将 GFramework.Cqrs.Benchmarks\** 排除于打包/编译/嵌入资源之外。
基准运行入口与 CI
GFramework.Cqrs.Benchmarks/Program.cs, GFramework.Cqrs.Benchmarks/README.md, .github/workflows/benchmark.yml
添加 BenchmarkDotNet 运行入口、中文 README 与可手动触发的基准 GitHub Actions(可按 filter 运行并上传 BenchmarkDotNet 产物)。
基准运行时与宿主构建
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs, GFramework.Cqrs.Benchmarks/Messaging/Fixture.cs, GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
提供创建“冻结”的 GFramework 容器、构建仅含当前基准的 MediatR ServiceProvider、场景验证与最小 ICqrsContext 实现。
生成调用器注册表(请求/流)
GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs, GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
为基准中的“生成器”路径提供 ICqrsHandlerRegistry / invoker provider 的注册表实现、描述符列表、DI 注册以及静态调度入口方法。
缓存与测试隔离工具
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
通过反射清除 CqrsDispatcher 的静态缓存字段(Notification/Request/Stream/Generated invokers),以支持单进程内的冷启动与路径间隔离。
基准套件实现
GFramework.Cqrs.Benchmarks/Messaging/*Benchmarks.cs (RequestBenchmarks, RequestInvokerBenchmarks, RequestPipelineBenchmarks, RequestStartupBenchmarks, StreamingBenchmarks, StreamInvokerBenchmarks, NotificationBenchmarks)
新增多组 BenchmarkDotNet 基准类,包含基线直接调用、GFramework(反射/生成)与 MediatR 三条路径的对比,覆盖请求、通知、流、管道深度、冷启动与调用器比较等场景;每套件注册对应请求/响应/处理器类型与 DI。
基准报告扩展
GFramework.Cqrs.Benchmarks/CustomColumn.cs
新增 BenchmarkDotNet 自定义列实现,用于在报告中插入场景/元数据列。
源生成器测试扩展
GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
新增 MixedRequestInvokerProviderSource 与 MixedStreamInvokerProviderSource 测试夹具,并添加两项测试,断言在混合(直接 + 反射)实现下生成的注册表/描述符与 Invoke 方法顺序稳定性。
文档与迁移追踪
ai-plan/public/cqrs-rewrite/...
更新迁移追踪与任务文档,新增 RP-083..RP-090 条目并将 PR #326 作为当前锚点与后续步骤建议。

Sequence Diagram(s)

sequenceDiagram
    participant Bench as "Benchmark Runner"
    participant Host as "BenchmarkHostFactory / DI"
    participant CQRS as "GFramework.Cqrs.Runtime"
    participant Med as "MediatR"
    participant Handler as "Handler"

    Bench->>Host: GlobalSetup() / 创建容器与服务提供者
    Host->>CQRS: 注册处理器、生成/反射注册表
    Host->>Med: 注册 MediatR 处理器
    Bench->>CQRS: 调用 Send/Publish/Stream
    CQRS->>Handler: 调用 已注册 Handler (反射或生成)
    Handler-->>CQRS: 返回结果 / 枚举
    Bench->>Med: 调用 MediatR Send/Publish/Stream
    Med->>Handler: 调用 MediatR Handler
    Handler-->>Med: 返回结果 / 枚举
    Bench->>Bench: 收集并记录基准结果(含自定义列)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • GeWuYou/GFramework#307:与本 PR 的生成流/请求调用器提供者描述符与注册表实现直接相关。
  • GeWuYou/GFramework#302:涉及源生成器与注册表生成逻辑,本 PR 中新增的有序性测试与生成注册表相互关联。
  • GeWuYou/GFramework#228:与 CqrsDispatcher 缓存/注册表变更相关,本 PR 的 BenchmarkDispatcherCacheHelper 针对相同内部缓存字段。
🚥 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 标题清晰准确地反映了PR的主要变更内容——添加一个全面的CQRS基准测试套件,包含反射和生成的调用者路径。
Docstring Coverage ✅ Passed Docstring coverage is 92.55% 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 6, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2282    ↑8 2282    ↑8 0 0 0 0 35.8s    ↓2.0s

Test Results

passed 2282 passed ↑8

Details

tests 2282 tests ↑8
clock 35.8s ↓2.0s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1060
pull-request Feat/cqrs optimization link #326

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2183 0 0 4.8s

build-and-test: Run #1060

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

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 9 4.2s 4.8s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 24 2.6s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 24 2.1s 2.2s
Generates_Scene_Behavior_Boilerplate 24 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 24 1.1s 1.1s
Append_ShouldNotBlock 24 1.0s 1.0s
Context_Caching_Should_Improve_Performance 24 784ms 795ms
PendingCount_ShouldReflectQueuedEntries 24 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 24 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 24 401ms 402ms

± Comparison with run #1055 at 043530f | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 24 runs.

Github Test Reporter by CTRF 💚

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
⚠️ CSHARP dotnet-format yes 1 no 5.77s
✅ REPOSITORY gitleaks yes no no 8.63s
✅ REPOSITORY trufflehog yes no no 6.22s

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 6, 2026

Greptile Summary

This PR introduces a standalone GFramework.Cqrs.Benchmarks project with a full suite of BenchmarkDotNet benchmarks covering notification, request, streaming, pipeline, and cold-start dispatch paths, plus a CI workflow to build and optionally run them on demand. It also adds a source-generator test for deterministic descriptor ordering and a centralized BenchmarkDispatcherCacheHelper that consolidates cache-clearing logic previously duplicated across three files.

  • All issues raised in the previous review round have been addressed: the dual-baseline category-grouping bug is fixed via AddLogicalGroupRules, cache clearing has been moved to [IterationSetup] (outside the measurement window), handler/behavior lifetimes are now symmetric between GFramework and MediatR across every benchmark class, the ClearDispatcherCache duplication is eliminated, and the shell-injection risk in the workflow is resolved by routing the user input through an environment variable before the shell consumes it.
  • The BenchmarkDispatcherCacheHelper centralises all reflection-based cache manipulation but remains tightly coupled to internal type and field names in GFramework.Cqrs.Internal.CqrsDispatcher; a rename in the production library will cause all benchmarks to abort at setup time rather than fail at compile time.

Confidence Score: 5/5

The change is purely additive — a new benchmark project excluded from the main build and one new test — with no modifications to production code paths.

All changes are confined to a standalone benchmark project and a test file. No production code is modified. Previously flagged issues have been resolved, and no new defects were found in the benchmark logic or CI workflow.

GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs — the reflection-based coupling to internal GFramework type names means a future rename could silently break all benchmark runs at setup time.

Important Files Changed

Filename Overview
.github/workflows/benchmark.yml New CI workflow for building/running benchmarks on demand; shell injection previously flagged is now correctly mitigated by routing the input through an env variable before the shell consumes it.
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs Centralised reflection-based cache-clearing helper extracted from three previously duplicated copies; works correctly but is tightly coupled to GFramework internal type names and field names.
GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs Previously flagged issues resolved: dual-baseline category grouping added via AddLogicalGroupRules, cache clearing moved to [IterationSetup], and handler lifetimes are now symmetric (both Transient).
GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs Clean steady-state benchmark comparing direct handler call, reflection dispatch, generated invoker dispatch, and MediatR; handler lifetimes are symmetric (Transient) across frameworks.
GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs Mirrors RequestInvokerBenchmarks for streaming paths; shared EnumerateAsync helper keeps enumeration bodies identical across all three handler types, isolating dispatch overhead cleanly.
GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs Pipeline benchmark with [Params(0,1,4)]; handler and pipeline behavior lifetimes are Singleton for both frameworks, making memory diagnoser numbers comparable.
GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs Steady-state notification publish benchmark; both handlers registered as Singleton instances, so allocation numbers are comparable between frameworks.
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs Well-structured factory centralising GFramework container and MediatR service-provider creation; TypeEvaluator filter prevents other benchmark handlers from polluting each class's MediatR registration.
GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs New test validating that the generated registry descriptor ordering is deterministic under mixed implementations; no issues found.
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj New standalone benchmark project correctly excluded from the main build; references BenchmarkDotNet 0.15.8 and MediatR 13.1.0 as comparison targets.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[BenchmarkDotNet Runner] --> B{Benchmark Class}
    B --> C[RequestStartupBenchmarks]
    B --> D[RequestInvokerBenchmarks]
    B --> E[StreamInvokerBenchmarks]
    B --> F[RequestPipelineBenchmarks]
    B --> G[NotificationBenchmarks]
    C --> CS1["[IterationSetup] ClearDispatcherCaches()"]
    CS1 --> CS2["Initialization_MediatR / GFrameworkCqrs"]
    CS1 --> CS3["ColdStart_MediatR / GFrameworkCqrs"]
    D --> DG["[GlobalSetup] ClearCaches + Build 3 runtimes"]
    DG --> DB1["SendRequest_Baseline (direct)"]
    DG --> DB2["SendRequest_GFrameworkReflection"]
    DG --> DB3["SendRequest_GFrameworkGenerated"]
    DG --> DB4["SendRequest_MediatR"]
    E --> EG["[GlobalSetup] ClearCaches + Build 3 stream runtimes"]
    EG --> EB1["Stream_Baseline / Reflection / Generated / MediatR"]
    F --> FP["[Params: 0,1,4] [GlobalSetup] ClearCaches"]
    FP --> FB1["SendRequest_Baseline / GFrameworkCqrs / MediatR"]
    G --> GS["[GlobalSetup] steady-state, no cache clearing"]
    GS --> GB1["PublishNotification_GFrameworkCqrs / MediatR"]
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs:35-48
**Brittle coupling to internal type and field names**

`ClearDispatcherCache` resolves `GFramework.Cqrs.Internal.CqrsDispatcher` and its five private static fields entirely by string. If any of those names is changed during a refactor (rename, access-modifier change, field consolidation), every benchmark that calls `ClearDispatcherCaches()` will fail at runtime — either with a `TypeLoadException` from `throwOnError: true`, or with the `InvalidOperationException` thrown for a missing field — rather than with a compile-time or source-generator error. Since this helper is the single gate-keeper for all cold-start and invoker benchmarks, a silent rename in the production library would cause every benchmark run to abort before a single measurement is taken. Consider exposing a thin `internal` test-seam on `CqrsDispatcher` so the coupling is validated at compile time.

Reviews (4): Last reviewed commit: "fix(cqrs): 收敛 benchmark review 收尾问题" | Re-trigger Greptile

Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs Outdated
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs Outdated
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: 4

🧹 Nitpick comments (1)
ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md (1)

57-81: 💤 Low value

「最近权威验证」节中同一构建命令重复记录 6 次,建议合并。

dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release 连同备注共出现 6 次(第 57–73 行),license-header.pygit diff --check 各重复 2 次(第 74–81 行)。作为 AI 规划文档,累积追加导致的冗余可以接受,但建议在下一次归档周期时合并为最终一次结果,保持文档可读性。

🤖 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 `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md` around
lines 57 - 81, The "最近权威验证" section contains repeated entries of the same
build/check commands (notably the command string `dotnet build
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
repeated six times and `python3 scripts/license-header.py --check` / `git diff
--check` repeated twice); collapse those duplicates by keeping a single
consolidated entry per unique command (e.g., one `dotnet build ... -c Release`
with a combined remark listing added benchmark/regression checkpoints such as
`StreamingBenchmarks`, `RequestPipelineBenchmarks`, `RequestStartupBenchmarks`,
`RequestInvokerBenchmarks`, and `StreamInvokerBenchmarks`) and similarly merge
the duplicate `license-header.py --check` and `git diff --check` lines into
single entries to improve readability while preserving all noted results.
🤖 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 453-466: The list item starting with "2. 若要继续贴近 `Mediator` 的
comparison benchmark 设计哲学…" is misplaced under the "### 验证(RP-089)" section;
move that paragraph back into the ordered list under "### 当前下一步(RP-089)" so that
the section order remains "当前下一步(RP-089)" followed by "### 验证(RP-089)", adjust
the numbering in the "当前下一步(RP-089)" list if needed, and ensure the stray item
text matches exact wording used elsewhere to avoid duplication.

In `@GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj`:
- Around line 17-19: The project is using MediatR 13.x which emits
license-warning logs (LuckyPennySoftware.MediatR.License) that will pollute
benchmark output; update the DI/logging setup or package versions: either set
the MediatR license key during service registration (configure the License Key
in your DI registration where MediatR is added), or add a logging filter to
exclude the LuckyPennySoftware.MediatR.License category in the benchmark host
logging configuration, and also bump BenchmarkDotNet from 0.15.6 to 0.15.8 in
GFramework.Cqrs.Benchmarks.csproj to pick up the latest fixes; reference the
PackageReference entries for MediatR and BenchmarkDotNet when making these
changes.

In `@GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs`:
- Around line 53-89: The two benchmarks measure different phases:
Initialization_MediatR resolves IMediator from the prebuilt container created in
Setup(), while Initialization_GFrameworkCqrs calls CreateGFrameworkRuntime()
creating a new container each iteration; fix by aligning phases—either (A) move
creation of _serviceProvider and _mediatr into the benchmark and have
Initialization_MediatR construct the provider via CreateMediatRServiceProvider()
so both methods build hosts, or (B) create the GFramework runtime once in
Setup() (call CreateGFrameworkRuntime() there and store it, e.g.,
_gframeworkRuntime) and change Initialization_GFrameworkCqrs() to return that
stored ICqrsRuntime so both benchmarks only resolve from an existing host;
update Cleanup() to dispose whichever stored host(s) you choose.
- Around line 118-133: The MediatR and GFramework setups use different
registration patterns causing duplicate handler registrations: in
CreateMediatRServiceProvider the handler is both AddSingleton and
auto-registered via RegisterServicesFromAssembly, while CreateGFrameworkRuntime
manually calls RegisterTransient for the handler; unify them by choosing one
registration strategy for both sides—either switch GFramework to assembly
scanning via RegisterCqrsHandlersFromAssembly or CqrsHandlerRegistryGenerator to
match MediatR’s RegisterServicesFromAssembly, or remove the duplicate
AddSingleton in CreateMediatRServiceProvider and rely only on manual
registrations (or vice versa); also replace the manual RegisterTransient call in
CreateGFrameworkRuntime with the recommended
RegisterCqrsHandlersFromAssembly/CqrsHandlerRegistryGenerator usage to follow
the startup rule.

---

Nitpick comments:
In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Around line 57-81: The "最近权威验证" section contains repeated entries of the same
build/check commands (notably the command string `dotnet build
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
repeated six times and `python3 scripts/license-header.py --check` / `git diff
--check` repeated twice); collapse those duplicates by keeping a single
consolidated entry per unique command (e.g., one `dotnet build ... -c Release`
with a combined remark listing added benchmark/regression checkpoints such as
`StreamingBenchmarks`, `RequestPipelineBenchmarks`, `RequestStartupBenchmarks`,
`RequestInvokerBenchmarks`, and `StreamInvokerBenchmarks`) and similarly merge
the duplicate `license-header.py --check` and `git diff --check` lines into
single entries to improve readability while preserving all noted results.
🪄 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: 2a723ee0-1a90-4f18-a03b-ec7b3b0638fc

📥 Commits

Reviewing files that changed from the base of the PR and between c01abac and 449eeb9.

📒 Files selected for processing (20)
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/README.md
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.csproj
  • GFramework.sln
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
👮 Files not reviewed due to content moderation or server errors (4)
  • GFramework.Cqrs.Benchmarks/Messaging/Fixture.cs
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
📜 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). (1)
  • GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (12)
**/*[!.]*

📄 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/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/README.md
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.sln
**/*.{xml,csproj,props,targets}

📄 CodeRabbit inference engine (AGENTS.md)

For XML/MSBuild files with XML declaration, keep XML declaration as first node and place license header immediately after it

Files:

  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.csproj
**/*.csproj

📄 CodeRabbit inference engine (AGENTS.md)

**/*.csproj: Follow repository defaults: ImplicitUsings disabled, Nullable enabled, GenerateDocumentationFile enabled for shipped libraries, LangVersion generally preview in main libraries and abstractions
Minimize new package dependencies. Add them only when necessary and keep scope narrow

Files:

  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.csproj
**/*.{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/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.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/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
**/*.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/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.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/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.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/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.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/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.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
**/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.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
**/*{Startup,Init,Register,Setup,Configure}*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

CQRS handler registration should use generated products from CqrsHandlerRegistryGenerator at runtime, falling back to reflection scanning when generation cannot cover cases; explicitly register handlers from non-default assemblies using RegisterCqrsHandlersFromAssembly(...) or RegisterCqrsHandlersFromAssemblies(...)

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
🧠 Learnings (2)
📚 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/Fixture.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Program.cs
  • GFramework.Cqrs.Benchmarks/CustomColumn.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.cs
  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
📚 Learning: 2026-04-16T13:25:59.124Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 235
File: GFramework.SourceGenerators.Tests/Rule/ContextAwareGeneratorSnapshotTests.cs:1-3
Timestamp: 2026-04-16T13:25:59.124Z
Learning: In the GeWuYou/GFramework repo, treat `global using NUnit.Framework;` as provided project-wide by `GFramework.SourceGenerators.Tests/GlobalUsings.cs` (via GlobalUsings.cs). Do not require or flag missing per-file `using NUnit.Framework;` directives in test `.cs` files under `GFramework.SourceGenerators.Tests/`, since the project-wide global usings already include NUnit (along with other common namespaces).

Applied to files:

  • GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
🪛 LanguageTool
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md

[grammar] ~431-~431: Use a hyphen to join words.
Context: ...registration / service lifetime 或 stream generated provider ### 阶段:stream invoke...

(QB_NEW_EN_HYPHEN)

🔇 Additional comments (6)
GFramework.Cqrs.Benchmarks/README.md (1)

1-46: LGTM — 文档内容与实际引入的文件结构一致。

GFramework.sln (1)

53-54: LGTM — 新项目注册格式与现有项目一致,GUID 唯一。

GFramework.csproj (1)

77-77: AI 摘要与代码不符:排除规则为新增(而非删除)。

摘要描述为"移除了对 GFramework.Cqrs.Benchmarks\** 目录的排除",但代码实际在 <None Remove><Compile Remove><EmbeddedResource Remove> 三个 ItemGroup 中各新增了一条针对 GFramework.Cqrs.Benchmarks\** 的排除规则,防止 benchmark 文件被意外打包进元包。代码行为正确,摘要方向相反。

GFramework.Cqrs.Benchmarks/Program.cs (1)

1-23: LGTM — 标准的 BenchmarkDotNet 入口实现,文档与命名均规范。

GFramework.Cqrs.Benchmarks/CustomColumn.cs (1)

16-71: LGTM — IColumn 接口实现完整,nullable 安全,主构造函数参数捕获委托的方式简洁正确。

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

8-17: 这个最小上下文拆分是合理的。

把 steady-state benchmark 所需的 ICqrsContext 降到最小,有助于避免把架构初始化噪音带进 dispatch 对比。

Comment thread ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md Outdated
Comment thread GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj Outdated
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs Outdated
@GeWuYou GeWuYou changed the title Feat/cqrs optimization Test/Add comprehensive CQRS benchmarking suite with reflection and generated invoker paths May 6, 2026
- 修复 RequestStartupBenchmarks 的 baseline 分组、初始化阶段对齐与 MediatR 重复注册问题
- 新增共享 dispatcher cache helper,并统一 benchmark 宿主的 MediatR logging/license 过滤配置
- 更新 cqrs-rewrite 跟踪与 trace,记录 PR #326 锚点、验证去重和 startup benchmark 的残留运行风险
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2282 2282 0 0 0 0 37.6s    ↑1.8s

Test Results

passed 2282 passed

Details

tests 2282 tests
clock 37.6s ↑1.8s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1061
pull-request Test/Add comprehensive CQRS benchmarking suite with reflection and generated invoker paths link #326

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2187 0 0 4.8s

build-and-test: Run #1061

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

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 10 4.2s 4.8s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 25 2.5s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 25 2.2s 2.2s
Generates_Scene_Behavior_Boilerplate 25 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 25 1.1s 1.1s
Append_ShouldNotBlock 25 1.0s 1.0s
Context_Caching_Should_Improve_Performance 25 784ms 795ms
PendingCount_ShouldReflectQueuedEntries 25 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 25 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 25 401ms 402ms

± Comparison with run #1060 at 496ca30 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 25 runs.

Github Test Reporter by CTRF 💚

Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs Outdated
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs Outdated
GeWuYou added 2 commits May 6, 2026 11:48
- 新增仅支持 workflow_dispatch 的 Benchmark workflow,默认只验证 benchmark 项目 Release build
- 补充可选 benchmark_filter 输入与 BenchmarkDotNet 工件上传,支持按场景手动执行基准测试
- 更新 cqrs-rewrite 跟踪与 trace,记录手动 benchmark workflow 的用途与当前 startup benchmark 残留风险
- 新增 BenchmarkHostFactory 统一 benchmark 最小宿主构建,并限制 MediatR 扫描到当前场景所需类型

- 修复 GFramework benchmark 容器未冻结导致的首次 handler 解析缺口,恢复 RequestStartupBenchmarks 冷启动结果

- 优化 request、pipeline、notification、stream 与 invoker benchmark 的生命周期对齐,减少无关程序集扫描噪音

- 更新 cqrs-rewrite 跟踪与追踪文档,记录 PR #326 benchmark review 收敛、根因和验证结果
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2282 2282 0 0 0 0 37.4s    ↓230ms

Test Results

passed 2282 passed

Details

tests 2282 tests
clock 37.4s ↓230ms
tool nunit
build CI - Build & Test arrow-right build-and-test link #1062
pull-request Test/Add comprehensive CQRS benchmarking suite with reflection and generated invoker paths link #326

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2190 0 0 4.8s

build-and-test: Run #1062

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

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 11 4.2s 4.8s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 26 2.4s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 26 2.2s 2.2s
Generates_Scene_Behavior_Boilerplate 26 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 26 1.1s 1.1s
Append_ShouldNotBlock 26 1.0s 1.0s
Context_Caching_Should_Improve_Performance 26 784ms 795ms
PendingCount_ShouldReflectQueuedEntries 26 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 26 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 26 401ms 402ms

± Comparison with run #1061 at 94f5d6f | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 26 runs.

Github Test Reporter by CTRF 💚

Comment thread .github/workflows/benchmark.yml Outdated
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: 8

♻️ Duplicate comments (2)
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj (1)

17-20: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

[已知问题] MediatR 13.x 许可证日志警告可能污染 benchmark 输出。

过去的 review 已指出:MediatR 13.x 在未配置 License Key 时,会在 LuckyPennySoftware.MediatR.License 分类下输出警告日志,干扰 BenchmarkDotNet 控制台输出的可读性。BenchmarkDotNet 版本已升至 0.15.8,但 MediatR 许可证过滤/配置部分仍需确认是否已在 BenchmarkHostFactory 或宿主日志配置中处理。

🤖 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/GFramework.Cqrs.Benchmarks.csproj` around lines 17
- 20, Benchmarks are still emitting MediatR license warnings from the
LuckyPennySoftware.MediatR.License logger; update the benchmark host setup
(e.g., BenchmarkHostFactory or wherever Host/ILogging is configured) to either
set the MediatR license key/environment variable or add a logging filter that
suppresses or raises the log level for the LuckyPennySoftware.MediatR.License
category so BenchmarkDotNet output is not polluted; search for
BenchmarkHostFactory and the host/ILogging configuration code and apply the
change there.
GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs (1)

133-158: ⚠️ Potential issue | 🟠 Major

冷启动基准仍然混入了不同的注册策略。

Line 142-145 走的是单点 RegisterTransient,但 Line 154-158 最终会通过 AddMediatR(...RegisterServicesFromAssembly(...)) 扫描程序集。这样 ColdStart_* 实际同时测了“手工注册 vs 程序集扫描+过滤”的差异,结果不能只解释为 startup / first-hit 成本。这里需要把两边统一到同一种注册路径。As per coding guidelines "**/*{Startup,Init,Register,Setup,Configure}*.cs: CQRS handler registration should use generated products from CqrsHandlerRegistryGenerator at runtime, falling back to reflection scanning when generation cannot cover cases; explicitly register handlers from non-default assemblies using RegisterCqrsHandlersFromAssembly(...) or RegisterCqrsHandlersFromAssemblies(...)`."

#!/bin/bash
# 验证当前 startup benchmark 两侧是否仍在使用不同的注册路径
rg -n -C3 --type=cs 'CreateGFrameworkRuntime\(|RegisterTransient<|CreateMediatRServiceProvider\(|RegisterServicesFromAssembly\(' GFramework.Cqrs.Benchmarks/Messaging
🤖 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/RequestStartupBenchmarks.cs` around
lines 133 - 158, The cold-start benchmark mixes two registration strategies:
CreateGFrameworkRuntime currently registers the handler with RegisterTransient
while CreateMediatRServiceProvider relies on
AddMediatR(...RegisterServicesFromAssembly...) — unify them by changing
GFramework side to use the same assembly-based handler registration pattern
required by our guidelines: replace the manual RegisterTransient call inside
CreateGFrameworkRuntime with a call to RegisterCqrsHandlersFromAssembly or
RegisterCqrsHandlersFromAssemblies (pointing at the assembly that contains
BenchmarkRequestHandler / RequestStartupBenchmarks) so both runtimes use
generated/assembly-based registration rather than manual per-type registration;
ensure any non-default assemblies are explicitly passed to the
RegisterCqrsHandlersFromAssembly(s) overload so reflection fallback or generator
output is used consistently.
🧹 Nitpick comments (3)
ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md (1)

50-126: ⚡ Quick win

建议压缩“最近权威验证”到“每类命令仅保留最新一次”

该段目前混合了多轮历史尝试与最新结论,和“唯一权威恢复锚点”定位不完全一致。建议在 active 文档只保留每类命令的最新结果(build/test/run/check 各一条),其余迁移到归档文档并链接。

As per coding guidelines, Keep code samples, package names, and command examples aligned with current repository state in documentation.

🤖 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 `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md` around
lines 50 - 126, Compress the “最近权威验证” section by keeping only the latest result
line for each command type (keep one each for dotnet run (benchmarks), dotnet
build, dotnet test, python3 scripts/license-header.py --check, and git diff
--check) and move all older per-command attempts into an archive/appendix doc
with links; update the retained lines to use the canonical command text shown
(e.g., the dotnet run --project GFramework.Cqrs.Benchmarks/... --filter
"*RequestStartupBenchmarks*" and python3 scripts/license-header.py --check
entries) and ensure the summary language and examples align with the
repository’s current naming/flags so code samples remain accurate.
GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs (2)

56-60: 💤 Low value

全局静态 LoggerFactoryResolver.Provider 的赋值未做隔离。

Setup 中直接覆盖了进程级静态字段 LoggerFactoryResolver.Provider,多个 Benchmark 类在同一宿主进程中按 BenchmarkDotNet 调度依次运行时会相互影响,且 Cleanup 未还原原值。若仅为 benchmark 用途可保留,但建议至少在注释中说明该副作用,或在 Cleanup 还原原值,避免对其他基准/测试类隐式干扰。

♻️ 备选修复
+    private ILoggerFactoryProvider? _previousLoggerProvider;
+
     [GlobalSetup]
     public void Setup()
     {
+        // 备份原 provider,Cleanup 时恢复,避免污染同进程内其他基准。
+        _previousLoggerProvider = LoggerFactoryResolver.Provider;
         LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider
         {
             MinLevel = LogLevel.Fatal
         };
@@
     [GlobalCleanup]
     public void Cleanup()
     {
         _serviceProvider.Dispose();
+        if (_previousLoggerProvider is not null)
+        {
+            LoggerFactoryResolver.Provider = _previousLoggerProvider;
+        }
     }

As per coding guidelines: "When adding caching, pooling, or shared mutable state, document thread-safety assumptions and failure modes".

🤖 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/RequestBenchmarks.cs` around lines 56 -
60, The benchmark Setup currently overwrites the process-global
LoggerFactoryResolver.Provider (via the call to Fixture.Setup("Request", ...))
without isolation; save the original provider before assigning
ConsoleLoggerFactoryProvider (reference LoggerFactoryResolver.Provider) and
restore that saved value in the corresponding Cleanup method, or if intentional,
add a clear comment in Setup documenting the global side-effect and
thread-safety assumptions so other benchmarks running in the same process are
not implicitly affected.

65-68: 💤 Low value

建议为 GFramework / MediatR 的同名契约引入 using 别名以提升可读性。

IRequest / IRequestHandler 在两边命名空间冲突,目前通过反复书写完整命名空间来消歧(L65、L68、L122–124、L136–137),可读性受损且容易在日后改动时漏改一处。可在文件顶部用 using 别名隔离两套契约,使用点保持简洁。

♻️ 别名示例
 using GFramework.Cqrs.Abstractions.Cqrs;
 using MediatR;
 using Microsoft.Extensions.DependencyInjection;
+using GfRequest = GFramework.Cqrs.Abstractions.Cqrs.IRequest<GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkResponse>;
+using GfRequestHandler = GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<
+    GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkRequest,
+    GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkResponse>;
+using MediatRRequest = MediatR.IRequest<GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkResponse>;
+using MediatRRequestHandler = MediatR.IRequestHandler<
+    GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkRequest,
+    GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkResponse>;

注意:因别名需引用嵌套类型,可能需要将 BenchmarkRequest / BenchmarkResponse 提升为顶层类型;若不愿改动结构,保持现状亦可。

Also applies to: 122-137

🤖 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/RequestBenchmarks.cs` around lines 65 -
68, Introduce type/namespace aliases to disambiguate the two
IRequest/IRequestHandler families and replace fully-qualified names; e.g. add
using GF = GFramework.Cqrs.Abstractions.Cqrs; and using MR = MediatR (or create
using GFRequestHandler =
GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<BenchmarkRequest,BenchmarkResponse>
/ MRRequestHandler = MediatR.IRequestHandler<BenchmarkRequest,BenchmarkResponse>
if you prefer type aliases), then update occurrences of
GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<BenchmarkRequest,
BenchmarkResponse> (and any plain IRequest/IRequestHandler uses around
BenchmarkRequest/BenchmarkResponse at the register and runtime calls) to use the
new aliases (e.g., GFRequestHandler or GF.IRequestHandler) so the code is
concise and unambiguous while keeping BenchmarkRequest and BenchmarkResponse
types consistent.
🤖 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 @.github/workflows/benchmark.yml:
- Around line 54-59: The step "Run filtered benchmarks" currently inlines ${{
inputs.benchmark_filter }} into the shell which enables shell injection;
instead, add an environment variable (e.g., BENCHMARK_FILTER) for that input and
reference it inside the run script with proper double-quotes (use
"$BENCHMARK_FILTER") so the value is passed as an argument to dotnet without
being interpreted by the shell; update the step to set env: BENCHMARK_FILTER:
${{ inputs.benchmark_filter }} and change the run invocation to use --filter
"$BENCHMARK_FILTER" (keep set -euo pipefail and quoting).

In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Around line 36-37:
文档中“当前活跃事实”和“最近权威验证”对同一基准(ColdStart_GFrameworkCqrs)结论互相矛盾:更新文档使两处结论一致,采用最新有效结论(即已恢复且不再报错的状态)作为主要显示,将早前记录的
“No CQRS request handler registered”
失败条目标记为已归档或移入归档节并在归档条目中注明时间戳和原因;同时检查并同步文档中的相关命令/示例/包名以反映当前仓库状态,确保在“当前活跃事实”、“最近权威验证”和归档节中只出现一致且有来源的结论(引用
ColdStart_GFrameworkCqrs 和 RequestStartupBenchmarks 来定位修改位置)。

In `@ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md`:
- Around line 259-262: The file contains a duplicated top-level secondary
heading "## 2026-05-06" (first occurrence at the top and again before the block
titled "### 阶段:mixed invoker provider 排序回归(CQRS-REWRITE-RP-083)"), which
triggers MD024; fix it by making the second heading unique—e.g., rename the
repeated "## 2026-05-06" to "## 2026-05-06 (RP-083…RP-089)" or "## 2026-05-06 —
phase: mixed invoker provider" so the header text is distinct and preserves the
related subheading "### 阶段:mixed invoker provider 排序回归(CQRS-REWRITE-RP-083)".

In `@GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs`:
- Around line 85-89: MicrosoftDiContainer currently holds disposable fields
ReaderWriterLockSlim (_lock) and IServiceProvider (_provider) but does not
implement IDisposable, causing resource leaks in benchmarks; implement
IDisposable on MicrosoftDiContainer (in
GFramework.Core/Ioc/MicrosoftDiContainer.cs), add a Dispose method that calls
_lock.Dispose() and, if _provider implements IDisposable, dispose it as well
(and suppress finalization if needed), and then update the benchmark Cleanup to
call Dispose on the _container instead of only disposing the service provider;
do not change CqrsDispatcher/_runtime disposal since it’s unnecessary.

In `@GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs`:
- Around line 76-96: The MediatR registration in the
CreateMediatRServiceProvider call (_serviceProvider) uses
ServiceLifetime.Singleton which mismatches the Transient lifetime used by the
GFramework reflection (RegisterTransient for ReflectionBenchmarkRequestHandler)
and generated handlers (RegisterCqrsHandlersFromAssembly); change the
ServiceLifetime argument in the CreateMediatRServiceProvider invocation from
ServiceLifetime.Singleton to ServiceLifetime.Transient so MediatR handlers
(e.g., MediatRBenchmarkRequestHandler) are constructed and cached consistently
with the other two paths, or alternatively add a concise comment next to the
CreateMediatRServiceProvider call explaining why Singleton is intentionally
required for this benchmark.

In `@GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs`:
- Around line 59-104: The benchmark leaks dispatcher pipeline chains across
scenarios because dispatcher caches aren’t cleared; add a call to
BenchmarkDispatcherCacheHelper.ClearDispatcherCaches() either at the end of
RequestPipelineBenchmarks.Setup() or at the start of
RequestPipelineBenchmarks.Cleanup() so the dispatcher cache is reset between
runs that reuse the same BenchmarkRequest type (controlled by
RequestPipelineCount) and avoid cross-contamination of
SendRequest_GFrameworkCqrs() results.
- Around line 261-279: The four derived classes BenchmarkPipelineBehavior1,
BenchmarkPipelineBehavior2, BenchmarkPipelineBehavior3 and
BenchmarkPipelineBehavior4 currently use an invalid C# declaration with a
trailing semicolon after the base type; replace the semicolon with an empty type
body (use { } instead of ;) so each class is declared as a sealed class
inheriting BenchmarkPipelineBehaviorBase with an empty body, e.g. public sealed
class BenchmarkPipelineBehavior1 : BenchmarkPipelineBehaviorBase { } and
likewise for the other three classes to restore valid syntax and allow
compilation.

In `@GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs`:
- Around line 76-96: The MediatR handler in StreamInvokerBenchmarks is
registered with ServiceLifetime.Singleton which mismatches the GFramework
registrations (transient) and skews benchmark results; update the call to
BenchmarkHostFactory.CreateMediatRServiceProvider (the invocation that currently
passes ServiceLifetime.Singleton for MediatRBenchmarkStreamHandler) to use
ServiceLifetime.Transient so the MediatR handler lifecycle matches GFramework's
transient handlers, or alternatively extract a separate benchmark targeting
singleton lifecycles if you intentionally want to compare differing lifetimes.

---

Duplicate comments:
In `@GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj`:
- Around line 17-20: Benchmarks are still emitting MediatR license warnings from
the LuckyPennySoftware.MediatR.License logger; update the benchmark host setup
(e.g., BenchmarkHostFactory or wherever Host/ILogging is configured) to either
set the MediatR license key/environment variable or add a logging filter that
suppresses or raises the log level for the LuckyPennySoftware.MediatR.License
category so BenchmarkDotNet output is not polluted; search for
BenchmarkHostFactory and the host/ILogging configuration code and apply the
change there.

In `@GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs`:
- Around line 133-158: The cold-start benchmark mixes two registration
strategies: CreateGFrameworkRuntime currently registers the handler with
RegisterTransient while CreateMediatRServiceProvider relies on
AddMediatR(...RegisterServicesFromAssembly...) — unify them by changing
GFramework side to use the same assembly-based handler registration pattern
required by our guidelines: replace the manual RegisterTransient call inside
CreateGFrameworkRuntime with a call to RegisterCqrsHandlersFromAssembly or
RegisterCqrsHandlersFromAssemblies (pointing at the assembly that contains
BenchmarkRequestHandler / RequestStartupBenchmarks) so both runtimes use
generated/assembly-based registration rather than manual per-type registration;
ensure any non-default assemblies are explicitly passed to the
RegisterCqrsHandlersFromAssembly(s) overload so reflection fallback or generator
output is used consistently.

---

Nitpick comments:
In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Around line 50-126: Compress the “最近权威验证” section by keeping only the latest
result line for each command type (keep one each for dotnet run (benchmarks),
dotnet build, dotnet test, python3 scripts/license-header.py --check, and git
diff --check) and move all older per-command attempts into an archive/appendix
doc with links; update the retained lines to use the canonical command text
shown (e.g., the dotnet run --project GFramework.Cqrs.Benchmarks/... --filter
"*RequestStartupBenchmarks*" and python3 scripts/license-header.py --check
entries) and ensure the summary language and examples align with the
repository’s current naming/flags so code samples remain accurate.

In `@GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs`:
- Around line 56-60: The benchmark Setup currently overwrites the process-global
LoggerFactoryResolver.Provider (via the call to Fixture.Setup("Request", ...))
without isolation; save the original provider before assigning
ConsoleLoggerFactoryProvider (reference LoggerFactoryResolver.Provider) and
restore that saved value in the corresponding Cleanup method, or if intentional,
add a clear comment in Setup documenting the global side-effect and
thread-safety assumptions so other benchmarks running in the same process are
not implicitly affected.
- Around line 65-68: Introduce type/namespace aliases to disambiguate the two
IRequest/IRequestHandler families and replace fully-qualified names; e.g. add
using GF = GFramework.Cqrs.Abstractions.Cqrs; and using MR = MediatR (or create
using GFRequestHandler =
GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<BenchmarkRequest,BenchmarkResponse>
/ MRRequestHandler = MediatR.IRequestHandler<BenchmarkRequest,BenchmarkResponse>
if you prefer type aliases), then update occurrences of
GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<BenchmarkRequest,
BenchmarkResponse> (and any plain IRequest/IRequestHandler uses around
BenchmarkRequest/BenchmarkResponse at the register and runtime calls) to use the
new aliases (e.g., GFRequestHandler or GF.IRequestHandler) so the code is
concise and unambiguous while keeping BenchmarkRequest and BenchmarkResponse
types consistent.
🪄 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: 9befa9e4-d103-4a59-aa09-98c6c19c0654

📥 Commits

Reviewing files that changed from the base of the PR and between 449eeb9 and 2cb6216.

📒 Files selected for processing (13)
  • .github/workflows/benchmark.yml
  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.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: Build and Test
  • GitHub Check: Code Quality & Security
🧰 Additional context used
📓 Path-based instructions (11)
**/*.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/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.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/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
**/*.{xml,csproj,props,targets}

📄 CodeRabbit inference engine (AGENTS.md)

For XML/MSBuild files with XML declaration, keep XML declaration as first node and place license header immediately after it

Files:

  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
**/*.csproj

📄 CodeRabbit inference engine (AGENTS.md)

**/*.csproj: Follow repository defaults: ImplicitUsings disabled, Nullable enabled, GenerateDocumentationFile enabled for shipped libraries, LangVersion generally preview in main libraries and abstractions
Minimize new package dependencies. Add them only when necessary and keep scope narrow

Files:

  • GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
**/*.{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
**/*{Startup,Init,Register,Setup,Configure}*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

CQRS handler registration should use generated products from CqrsHandlerRegistryGenerator at runtime, falling back to reflection scanning when generation cannot cover cases; explicitly register handlers from non-default assemblies using RegisterCqrsHandlersFromAssembly(...) or RegisterCqrsHandlersFromAssemblies(...)

Files:

  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
🧠 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/BenchmarkHostFactory.cs
  • GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
  • GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
🪛 LanguageTool
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md

[grammar] ~475-~475: Use a hyphen to join words.
Context: ...registration / service lifetime 或 stream generated provider ### 阶段:stream invoke...

(QB_NEW_EN_HYPHEN)


[uncategorized] ~516-~516: The official name of this software platform is spelled with a capital “H”.
Context: ...ark workflow(CQRS-REWRITE-RP-089) - 新增 .github/workflows/benchmark.yml,提供仅 `workflow_...

(GITHUB)


[grammar] ~516-~516: Ensure spelling is correct
Context: ...提供仅 workflow_dispatch 触发的 benchmark 入口 - workflow 默认只执行 GFramework.Cqrs.Benchmarks 的 Re...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.22.1)
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md

[warning] 260-260: Multiple headings with the same content

(MD024, no-duplicate-heading)

🔇 Additional comments (1)
GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs (1)

83-87: ⚡ Quick win

无需修改 Cleanup() 方法 — _container 不实现 IDisposable

MicrosoftDiContainer 不实现 IDisposable 接口。其继承链为:MicrosoftDiContainerContextAwareBaseIContextAware,均不涉及 IDisposable。因此无需在 Cleanup() 中释放 _container。当前代码正确地释放了 _serviceProvider(Microsoft.Extensions.DependencyInjection 的 ServiceProvider 确实实现了 IDisposable)。

			> Likely an incorrect or invalid review comment.

Comment thread .github/workflows/benchmark.yml Outdated
Comment thread ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md Outdated
Comment thread ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs Outdated
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs
Comment thread GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs Outdated
Comment thread GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs Outdated
- 修复 benchmark workflow 过滤器输入的 shell 注入风险

- 统一 request 与 stream invoker 基准中 MediatR handler 的生命周期基线

- 更新 request pipeline benchmark 的缓存清理与空行为类型声明

- 压缩 cqrs-rewrite active 跟踪与 trace,记录本轮 PR review 收尾结论
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2282 2282 0 0 0 0 37.9s    ↑470ms

Test Results

passed 2282 passed

Details

tests 2282 tests
clock 37.9s ↑470ms
tool nunit
build CI - Build & Test arrow-right build-and-test link #1063
pull-request Test/Add comprehensive CQRS benchmarking suite with reflection and generated invoker paths link #326

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2194 0 0 4.8s

build-and-test: Run #1063

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

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 12 4.3s 4.8s
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 27 2.3s 4.7s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 27 2.2s 2.3s
Generates_Scene_Behavior_Boilerplate 27 1.9s 2.0s
CleanupDuringAcquire_Should_NotCauseRaceCondition 27 1.1s 1.1s
Append_ShouldNotBlock 27 1.0s 1.0s
Context_Caching_Should_Improve_Performance 27 784ms 795ms
PendingCount_ShouldReflectQueuedEntries 27 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 27 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 27 401ms 402ms

± Comparison with run #1062 at 5aba9a1 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 27 runs.

Github Test Reporter by CTRF 💚

@GeWuYou
Copy link
Copy Markdown
Owner Author

GeWuYou commented May 6, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 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 109bce6 into main May 6, 2026
7 checks passed
@GeWuYou GeWuYou deleted the feat/cqrs-optimization branch May 6, 2026 06:29
This was referenced May 8, 2026
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