Feat/cqrs optimization#345
Conversation
- 优化 CqrsDispatcher 的 CreateStream 热路径,按 dispatcher 实例缓存 stream pipeline behavior 的服务可见性 - 新增 stream presence cache 回归与最小测试桩,锁住同容器共享、跨容器隔离的缓存语义 - 更新 cqrs-rewrite 恢复文档并补充本轮 stream benchmark 验证结果
- 新增 request lifetime benchmark 的 generated registry,提供最小 generated request descriptor。 - 更新 RequestLifetimeBenchmarks 使用 generated-provider 宿主,并保留 Singleton/Transient 生命周期矩阵控制。 - 补充 dispatcher 缓存清理,避免生命周期矩阵之间互相污染 benchmark 结果。
- 拆分 GFramework stream lifetime benchmark 的 reflection、generated 与 MediatR 独立请求和 handler 类型 - 调整 generated stream registry 仅绑定 generated 口径,避免静态 dispatcher 缓存污染对照结果 - 验证 StreamLifetimeBenchmarks 在 Singleton 与 Transient 下均产出完整四方对照结果
- 更新 active tracking 的恢复点、branch diff 与 benchmark 口径。 - 补充 request lifetime 与 stream lifetime 的最新权威验证结果。 - 推进 trace 到 RP-125 与 RP-126,并记录下一推荐步骤。
- 更新 RequestLifetimeBenchmarks 的 generated-provider 宿主说明 - 更新 StreamLifetimeBenchmarks 的 reflection/generated/MediatR 对照口径说明 - 补充 benchmark 工程的最小构建与过滤运行示例
- 新增 gframework-multi-agent-batch skill 及其公开入口说明 - 更新 AGENTS.md 中主 Agent 协调多 worker 的职责与停机约束 - 补充 ai-plan-governance 主题的 public recovery 入口与验证记录
- 优化 generated stream dispatch binding 为按响应类型缓存强类型 invoker 与 pipeline executor,压缩 CreateStream 热路径桥接开销 - 保持 stream 异常契约与行为缓存语义不变,并补齐相关 XML 注释与必要内联说明 - 补充 generated stream binding 与 pipeline executor 复用回归,覆盖 generated invoker 与 stream pipeline 组合场景
- 新增 StreamLifetimeBenchmarks 的 FirstItem 与 DrainAll 观测模式,用于拆分建流瞬时成本与完整枚举成本 - 更新 cqrs-rewrite 恢复文档与 benchmark README,同步 RP-127 的验证结果、branch diff 与下一恢复点
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (6)!({.agents,ai-libs,third-party-licenses,scripts/license-header.py}/**)**/*.{cs,csproj,xml,yml,yaml,json,ts,js,ps1,sh,py}📄 CodeRabbit inference engine (AGENTS.md)
Files:
ai-plan/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
ai-plan/public/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
ai-plan/public/*/todos/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
ai-plan/public/**/{todos,traces}/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
ai-plan/public/*/traces/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (1)📓 Common learnings🔇 Additional comments (1)
📝 WalkthroughWalkthrough新增 gframework-multi-agent-batch 技能与多 Agent 协作治理文档(README/AGENTS.md/ai-plan-governance),并将 CqrsDispatcher 的流分发重构为泛型强类型绑定与管道执行器,配套更新基准、生成器注册表与缓存验证测试。 Changes多Agent协调治理
CQRS 流类型安全与基准测试
预估代码审查工作量🎯 4 (Complex) | ⏱️ ~45分钟 可能相关的 PR
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Test ResultsDetails
Insights
Fail Rate
build-and-test: Run #1100
🎉 All tests passed!Slowest Tests
± Comparison with run #1099 at 0141e3d | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 45 runs. Github Test Reporter by CTRF 💚 |
|
| Filename | Overview |
|---|---|
| GFramework.Cqrs/Internal/CqrsDispatcher.cs | Core stream dispatch path fully generified: replaces weakly-typed StreamDispatchBinding with StreamDispatchBinding, adds StreamDispatchBindingBox for unified cache storage, adds per-instance _streamBehaviorPresenceCache to avoid redundant container HasRegistration calls on the zero-pipeline path. |
| GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs | New test handler for zero-pipeline stream cache path; async IAsyncEnumerable Handle() has no await expression, which will produce a CS1998 build warning. |
| GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs | Adds stream behavior presence caching test and stream dispatch binding inspection helpers; AssertSharedStreamDispatcherCacheState has a symmetry gap for twoPipelineBehaviorType assertions. |
| GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs | Adds generated stream binding and executor reuse test with correct identity assertions across two dispatches. |
| GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs | Splits into Reflection/Generated/MediatR paths, adds StreamObservation param, extracts shared EnumerateAsync; two containers managed independently with correct cleanup. |
| GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.cs | New hand-written generated registry for request lifetime benchmarks; correctly implements all required CQRS registry interfaces. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
CS["CqrsDispatcher.CreateStream<TResponse>(request)"]
GSD["GetStreamDispatchBinding<TResponse>(requestType)"]
WTC["WeakTypePairCache<StreamDispatchBindingBox>\n(process-level)"]
HIT{"Cache hit?"}
CREATE["CreateStreamDispatchBindingBox<TResponse>()"]
GEN{"Generated invoker available?"}
ADAPT["GeneratedStreamInvokerAdapter<TResponse>\nwraps WeakStreamInvoker"]
REFLECT["CreateStreamInvoker<TResponse>\n(reflection, once per type)"]
BOX["StreamDispatchBindingBox<TResponse>.Get<TResponse>()"]
BINDING["StreamDispatchBinding<TResponse>\n(handler + invoker + pipeline executor cache)"]
BPC["HasStreamBehaviorRegistration\n_streamBehaviorPresenceCache (per-dispatcher)"]
ZERO{"Behaviors registered?"}
DIRECT["Direct handler call"]
PIPE["GetPipelineExecutor(count)\nStreamPipelineExecutor<TResponse>"]
CS --> GSD --> WTC --> HIT
HIT -- miss --> CREATE
HIT -- hit --> BOX
CREATE --> GEN
GEN -- yes --> ADAPT --> BOX
GEN -- no --> REFLECT --> BOX
BOX --> BINDING --> BPC --> ZERO
ZERO -- false --> DIRECT
ZERO -- true --> PIPE
Comments Outside Diff (1)
-
GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs, line 22-34 (link)asynciterator withoutawait→ CS1998 build warningHandleis declaredasync IAsyncEnumerable<int>but contains noawaitexpression. The C# compiler emits CS1998 ("Async method lacks 'await' operators and will run synchronously") for this case, even for async iterators. The benchmarks inStreamLifetimeBenchmarksaddress the identical pattern by appendingawait Task.CompletedTask.ConfigureAwait(false)inside the loop; the same fix is needed here. Per AGENTS.md, build warnings in touched modules must be resolved in the same change.Context Used: AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review. Path: GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs Line: 22-34 Comment: **`async` iterator without `await` → CS1998 build warning** `Handle` is declared `async IAsyncEnumerable<int>` but contains no `await` expression. The C# compiler emits CS1998 ("Async method lacks 'await' operators and will run synchronously") for this case, even for async iterators. The benchmarks in `StreamLifetimeBenchmarks` address the identical pattern by appending `await Task.CompletedTask.ConfigureAwait(false)` inside the loop; the same fix is needed here. Per AGENTS.md, build warnings in touched modules must be resolved in the same change. **Context Used:** AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0cd0e33d-2941-4978-a8b6-a9a798ff17fd)) How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.cs:22-34
**`async` iterator without `await` → CS1998 build warning**
`Handle` is declared `async IAsyncEnumerable<int>` but contains no `await` expression. The C# compiler emits CS1998 ("Async method lacks 'await' operators and will run synchronously") for this case, even for async iterators. The benchmarks in `StreamLifetimeBenchmarks` address the identical pattern by appending `await Task.CompletedTask.ConfigureAwait(false)` inside the loop; the same fix is needed here. Per AGENTS.md, build warnings in touched modules must be resolved in the same change.
### Issue 2 of 3
GFramework.Cqrs/Internal/CqrsDispatcher.cs:497-502
The `StreamInvoker<TResponse>` lambda is an unnecessary wrapper allocation. `adapter.Invoke` is already a method group with the exact signature matching `StreamInvoker<TResponse>`, so it can be assigned directly. Since the binding creation path is cached, the cost is amortized, but the lambda form allocates an extra closure object around the adapter on every first-use of a type pair.
```suggestion
// generated stream descriptor 的公开契约仍以 object 返回值暴露异步流;
// 这里在 binding 创建时只做一次适配,把后续 CreateStream 热路径保持为强类型调用。
var adapter = new GeneratedStreamInvokerAdapter<TResponse>(weakInvoker);
return new StreamInvokerDescriptor<TResponse>(descriptor.HandlerType, adapter.Invoke);
```
### Issue 3 of 3
GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs:846-874
**`AssertSharedStreamDispatcherCacheState` does not assert `twoPipelineBehaviorType` on `secondDispatcher` / `isolatedDispatcher`**
The helper verifies `zeroPipelineBehaviorType` on both shared and isolated dispatchers, but `twoPipelinePresence` is only checked as a bare value equality against `expectedTwoPipelinePresence` — it is never verified that `secondDispatcher` and `isolatedDispatcher` reflect the correct state for `twoPipelineBehaviorType`. The symmetry with the `zeroPipelineBehaviorType` assertions is missing, so a regression where the two-pipeline cache entry leaks across dispatcher instances could go undetected.
Reviews (2): Last reviewed commit: "docs(cqrs): 收口PR345评审反馈" | Re-trigger Greptile
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|
| dotnet-format | yes | 1 | no | 4.59s | ||
| ✅ REPOSITORY | gitleaks | yes | no | no | 8.51s | |
| ✅ REPOSITORY | trufflehog | yes | no | no | 7.17s |
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

Show us your support by starring ⭐ the repository
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
AGENTS.md (1)
138-170: ⚡ Quick win建议明确"budget"相关术语的含义。
新增的多智能体协调规则结构清晰、职责明确,为并行工作提供了完善的治理框架。然而,文中多次使用了 "branch-diff budget"(第 154 行)、"reviewability budget"(第 154 行)、"context-budget posture"(第 158 行)和 "context-budget signal"(第 167 行)等术语,但在
AGENTS.md中未见这些概念的定义。如果这些术语在
$gframework-multi-agent-batch技能文档中有详细说明,建议在此处添加交叉引用;否则建议在本文档中简要说明这些预算限制的含义,以便新贡献者理解何时应停止派生 worker。💡 建议的补充说明示例
可以在第 138 行"Multi-Agent Coordination Rules"标题后添加简短说明:
### Multi-Agent Coordination Rules + +- **Branch-diff budget**: the maximum acceptable number of changed lines or files before the batch becomes difficult to review. +- **Context-budget**: the main agent's remaining context window capacity for tracking active workers and integrating results. +- **Reviewability budget**: the cumulative complexity threshold beyond which accepting more parallel changes would compromise review quality.或者添加到技能文档的引用:
- When a complex task uses multiple workers, the main agent SHOULD prefer the public workflow documented by - `$gframework-multi-agent-batch` unless a more task-specific skill already provides stricter rules. + `$gframework-multi-agent-batch` (which defines branch-diff, context-budget, and reviewability constraints) unless + a more task-specific skill already provides stricter rules.🤖 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 `@AGENTS.md` around lines 138 - 170, The document uses undefined budget terms (branch-diff budget, reviewability budget, context-budget posture/signal) inside the "Multi-Agent Coordination Rules"; add a short glossary paragraph immediately after the "Multi-Agent Coordination Rules" header that (1) defines each term in one sentence (what it measures and its threshold intent), (2) states how they affect worker-launch decisions, and (3) if detailed definitions exist in the $gframework-multi-agent-batch skill, add a one-line cross-reference to that skill (include the exact symbol $gframework-multi-agent-batch) so readers can follow for full rules; update any nearby bullets to use the clarified terms if wording becomes ambiguous.GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs (3)
316-326: 💤 Low value
GetAsyncEnumerator()未传入CancellationToken
ConsumeFirstItemAsync直接调用responses.GetAsyncEnumerator(),没有显式把取消令牌穿过来。当前 baseline /MediatR/ GFramework 路径在 benchmark 中都使用CancellationToken.None,所以行为上不会有差异;但若后续把这个 helper 复用到带真实取消语义的场景,就会丢失[EnumeratorCancellation]的传播路径。建议显式接受并向下传递取消令牌,使 helper 自身保持取消可见性。♻️ 建议修改
- private static async ValueTask ConsumeFirstItemAsync<TResponse>(IAsyncEnumerable<TResponse> responses) + private static async ValueTask ConsumeFirstItemAsync<TResponse>( + IAsyncEnumerable<TResponse> responses, + CancellationToken cancellationToken = default) { - var enumerator = responses.GetAsyncEnumerator(); + var enumerator = responses.GetAsyncEnumerator(cancellationToken); await using (enumerator.ConfigureAwait(false)) { if (await enumerator.MoveNextAsync().ConfigureAwait(false)) { _ = enumerator.Current; } } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs` around lines 316 - 326, ConsumeFirstItemAsync currently calls responses.GetAsyncEnumerator() without a CancellationToken, losing cancellation propagation; update the method signature of ConsumeFirstItemAsync<TResponse> to accept a CancellationToken (e.g., cancellationToken) and pass it into responses.GetAsyncEnumerator(cancellationToken). Ensure all internal awaits still use ConfigureAwait(false) and that callers supply CancellationToken.None where appropriate so the helper preserves enumerator cancellation semantics.
459-471: 💤 Low value
[EnumeratorCancellation]可以改为短名引用
EnumerateAsync的特性参数仍写成[System.Runtime.CompilerServices.EnumeratorCancellation],而文件顶部并未把System.Runtime.CompilerServices列入using,与本仓库要求"using集中在文件顶部并保持一致"的风格不太一致。建议在顶部加入using System.Runtime.CompilerServices;后改为[EnumeratorCancellation],避免方法签名出现一段长的内联命名空间。♻️ 建议修改
using BenchmarkDotNet.Order; using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks;private static async IAsyncEnumerable<TResponse> EnumerateAsync<TResponse>( Guid id, int itemCount, Func<Guid, TResponse> responseFactory, - [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken) + [EnumeratorCancellation] CancellationToken cancellationToken)As per coding guidelines: "Keep
usingdirectives at the top of the file and sort them consistently".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs` around lines 459 - 471, The attribute on the EnumerateAsync method currently uses the fully-qualified System.Runtime.CompilerServices.EnumeratorCancellation; add a top-of-file using System.Runtime.CompilerServices; and change the method parameter attribute to [EnumeratorCancellation] so the signature no longer contains the long inline namespace; update any using ordering to match the repository's sorted/top-of-file style.
26-30: 💤 Low value类级
<remarks>未提及新增的Observation维度类摘要已经改为"对比 stream 在不同 handler 生命周期与观测方式下的额外开销",但
<remarks>仍只解释Scoped维度的边界,没有说明本轮新增的FirstItem / DrainAll观测维度的取舍(为什么不再只 drain、为什么不引入IgnoreFirstItem之外的更多模式等)。建议在同一个<remarks>段补一行解释观测维度边界,避免后续维护者在阅读这个 benchmark 时只知道"有 enum"但不知道为何选这两种。As per coding guidelines: "XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs` around lines 26 - 30, Update the class-level XML <remarks> in StreamLifetimeBenchmarks to explicitly document the new Observation dimension: mention the Observation enum and the chosen modes (FirstItem and DrainAll), explain what each mode measures (e.g., first-item latency vs. full-drain throughput/overhead), and state why other observation patterns were omitted (to keep scope focused on minimal per-item vs. full-stream cost and to avoid conflating additional measurement strategies with lifecycle comparisons); reference the Observation enum and the StreamLifetimeBenchmarks class so future readers understand the intent, constraints, and usage of these two observation modes.
🤖 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/todos/cqrs-rewrite-migration-tracking.md`:
- Line 12: Update the recovery document (cqrs-rewrite-migration-tracking.md) so
the PR anchor reflects the actual active PR: change the current mention of "PR
`#344`" to "PR `#345`" (feat/cqrs-optimization) and ensure the RP-127 recovery point
is clearly tied to PR `#345`; additionally, verify the document includes the
required recovery metadata per guidelines: current phase, active recovery point
identifier, known risks, and the next recommended resume step so another
contributor or subagent can continue safely.
- Line 22: The document reports conflicting branch-diff totals: line 22 states
"21 files (1231 insertions / 181 deletions)" while line 78 states "10 files (556
insertions / 75 deletions)"; re-check the diff counts against the same baseline
commit id d85828c5 (origin/main) and update the "当前结论" and/or "当前活跃事实" entries
so they present the same reconciled totals (files, insertions, deletions)
derived from a single git diff run; ensure the baseline commit id d85828c5
remains referenced and that both the summary at line 22 and the detail at line
78 are consistent.
- Line 88: Update the outdated single-dimension stream lifetime statement (the
line starting "当前 stream lifetime benchmark 已补齐 ...") to the RP-127 validated
dual-dimension format (FirstItem / DrainAll) used in the "当前结论" block; replace
the old singleton/transient single values with the four-number matrix that
matches the authoritative validation entries found in the recent results (see
the validated numbers recorded around lines 162-164) so the "当前活跃事实" mirrors the
RP-127 FirstItem/DrainAll results exactly.
In `@GFramework.Cqrs.Benchmarks/README.md`:
- Line 64: Remove the governance recovery ID "RP-127" from the README and
replace the RP-127-dependent phrasing with a neutral, consumer-facing
observation: state the measured outcomes for StreamLifetimeBenchmarks (e.g.,
under Singleton generated slightly outperforms reflection for FirstItem and
DrainAll; under Transient reflection slightly outperforms generated for
FirstItem while generated outperforms reflection for DrainAll) and rephrase the
sentence about future work (“若继续沿 RP-127 收口 stream lifetime”) to describe the
capability/impact dimension (e.g., “如果继续优化 stream lifetime…”) rather than
referencing the recovery point; relocate any RP-127 audit or trace details into
the contributor-only ai-plan/public/cqrs-rewrite/** area.
---
Nitpick comments:
In `@AGENTS.md`:
- Around line 138-170: The document uses undefined budget terms (branch-diff
budget, reviewability budget, context-budget posture/signal) inside the
"Multi-Agent Coordination Rules"; add a short glossary paragraph immediately
after the "Multi-Agent Coordination Rules" header that (1) defines each term in
one sentence (what it measures and its threshold intent), (2) states how they
affect worker-launch decisions, and (3) if detailed definitions exist in the
$gframework-multi-agent-batch skill, add a one-line cross-reference to that
skill (include the exact symbol $gframework-multi-agent-batch) so readers can
follow for full rules; update any nearby bullets to use the clarified terms if
wording becomes ambiguous.
In `@GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs`:
- Around line 316-326: ConsumeFirstItemAsync currently calls
responses.GetAsyncEnumerator() without a CancellationToken, losing cancellation
propagation; update the method signature of ConsumeFirstItemAsync<TResponse> to
accept a CancellationToken (e.g., cancellationToken) and pass it into
responses.GetAsyncEnumerator(cancellationToken). Ensure all internal awaits
still use ConfigureAwait(false) and that callers supply CancellationToken.None
where appropriate so the helper preserves enumerator cancellation semantics.
- Around line 459-471: The attribute on the EnumerateAsync method currently uses
the fully-qualified System.Runtime.CompilerServices.EnumeratorCancellation; add
a top-of-file using System.Runtime.CompilerServices; and change the method
parameter attribute to [EnumeratorCancellation] so the signature no longer
contains the long inline namespace; update any using ordering to match the
repository's sorted/top-of-file style.
- Around line 26-30: Update the class-level XML <remarks> in
StreamLifetimeBenchmarks to explicitly document the new Observation dimension:
mention the Observation enum and the chosen modes (FirstItem and DrainAll),
explain what each mode measures (e.g., first-item latency vs. full-drain
throughput/overhead), and state why other observation patterns were omitted (to
keep scope focused on minimal per-item vs. full-stream cost and to avoid
conflating additional measurement strategies with lifecycle comparisons);
reference the Observation enum and the StreamLifetimeBenchmarks class so future
readers understand the intent, constraints, and usage of these two observation
modes.
🪄 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: 96c038a0-1be3-4309-bc5e-69b077c1467a
📒 Files selected for processing (21)
.agents/skills/README.md.agents/skills/gframework-batch-boot/SKILL.md.agents/skills/gframework-boot/SKILL.md.agents/skills/gframework-multi-agent-batch/SKILL.md.agents/skills/gframework-multi-agent-batch/agents/openai.yamlAGENTS.mdGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.csGFramework.Cqrs.Benchmarks/README.mdGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.csGFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.csGFramework.Cqrs/Internal/CqrsDispatcher.csai-plan/public/README.mdai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.mdai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-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). (1)
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (8)
**/README.md
📄 CodeRabbit inference engine (AGENTS.md)
Use the canonical filename
README.mdfor module documentation; do not introduce newReadMe.mdor other filename variantsA module README MUST describe the module's purpose, the relationship to adjacent runtime, abstractions, or generator packages, the major subdirectories or subsystems the reader is expected to use, the minimum adoption path, and the corresponding
docs/zh-CN/entry pointsIf a module's responsibilities, setup, public API surface, generator inputs, or adoption path change, update that module's
README.mdin the same change
Files:
ai-plan/public/README.mdGFramework.Cqrs.Benchmarks/README.md
ai-plan/**
📄 CodeRabbit inference engine (AGENTS.md)
When implementation plans, traces, reviews, or design notes reference a third-party project, prefer the repository-local path under
ai-libs/instead of an unspecified upstream repositoryIf a task depends on observations from
ai-libs/**, record the referenced path and conclusion in the active plan or trace when the work is multi-step or complex, or when an active tracking document already existsNever write secrets, tokens, credentials, private keys, machine usernames, home-directory paths, hostnames, IP addresses, proprietary URLs, or other sensitive environment details into any
ai-plan/**fileNever record absolute file-system paths in
ai-plan/**; use repository-relative paths, branch names, PR numbers, or stable document identifiers instead
Files:
ai-plan/public/README.mdai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md
ai-plan/public/**
📄 CodeRabbit inference engine (AGENTS.md)
Contributors MUST keep committed
ai-plan/public/**content safe to publish in Git historyTracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended recovery point
When a stage inside an active topic is fully complete, move the finished artifacts into that topic's
archive/directory instead of leaving every completed step in the default boot pathWhen a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery document and the trace at each meaningful milestone before pausing or handing work off
If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in the active recovery document or trace before continuing implementation
Files:
ai-plan/public/README.mdai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md
ai-plan/public/README.md
📄 CodeRabbit inference engine (AGENTS.md)
ai-plan/public/README.mdMUST list only active topics; do not addai-plan/public/archive/**content to the default boot indexWhen a worktree-to-topic mapping changes, or when a topic becomes active/inactive, contributors MUST update
ai-plan/public/README.mdin the same changeWhen a topic is fully complete, move the entire topic directory under
ai-plan/public/archive/<topic>/and remove it fromai-plan/public/README.mdin the same change
Files:
ai-plan/public/README.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.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.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 logicAll public, protected, and internal types and members MUST include XML documentation comments (
///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicableXML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds or compatibility constraints, and registration order or lifecycle sequencing
Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and generator pipelines MUST explain what is generated, why it is generated, the semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every required
usingexplicitlyWrite null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespace pattern
GFramework.{Module}.{Feature}with PascalCase segmentsFollow standard C# naming: types, methods, properties, events, and constants use PascalCase; interfaces use
Iprefix; parameters and locals use camelCase; private fields use_camelCaseFramework runtime, abstractions, and meta-package projects MUST NOT reference
*.SourceGenerators*projects...
Files:
GFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs/Internal/CqrsDispatcher.csGFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.cs
ai-plan/public/*/traces/**
📄 CodeRabbit inference engine (AGENTS.md)
Contributors MUST maintain a matching execution trace under
ai-plan/public/<topic>/traces/for complex work, recording the current date, key decisions, validation milestones, and the immediate next step
Files:
ai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
ai-plan/public/*/todos/**
📄 CodeRabbit inference engine (AGENTS.md)
When working from a tracked implementation plan, contributors MUST update the corresponding tracking document under
ai-plan/public/<topic>/todos/in the same changeRecovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next recommended resume step so another contributor or subagent can continue the work safely
Files:
ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Read `@.ai/environment/tools.ai.yaml` before choosing runtimes or CLI tools; prefer project-relevant tools listed there instead of assuming every installed system tool is fair game
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: In WSL environments against Windows-backed worktrees, prefer Linux `git` with explicit `--git-dir=<repo>/.git/worktrees/<worktree-name>` and `--work-tree=<worktree-root>` binding for every repository command
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Every completed task MUST pass at least one build validation before it is considered done
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: When inspecting or reducing warnings during project build, establish the warning baseline from a non-incremental repository-root build by running `dotnet clean` and then `dotnet build`
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Commit messages MUST use Conventional Commits format: `<type>(<scope>): <summary>` with commit summary in simplified Chinese
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Commit body MUST use unordered list items with each item starting with a verb such as `新增`、`修复`、`优化`、`更新`、`补充`、`重构`
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use `feat` only for user-facing or consumer-facing capability additions; use `fix` for behavior corrections; use `perf` for observable performance improvements; use `refactor` only for non-feature code restructuring; use `deps` for dependency updates; use `security` for vulnerability fixes; use `docs`、`test`、`chore`、`build`、`ci`、`style` for their literal categories
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Documentation-only changes MUST NOT use `feat`, including new guides, refreshed examples, navigation updates, and adoption notes for existing capabilities
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: New task branches should follow naming rule `<type>/<topic-or-scope>`, where `<type>` should match the intended Conventional Commit category
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Repository-maintained source and configuration files that are supported by `scripts/license-header.py` MUST include an Apache-2.0 file header before the task is considered complete
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Before committing changes that add or modify supported source/configuration files, run `python3 scripts/license-header.py --check` and resolve any missing or misplaced headers
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: For files with shebang lines, keep the shebang as the first line and place the license header immediately after it
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Do not add project license headers to excluded or third-party areas such as `.agents/**`, `ai-libs/**`, `third-party-licenses/**`, generated snapshots, binary assets, lock files, and generated build output
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Prefer invoking `$gframework-boot` when the user uses short startup prompts such as `boot`、`continue`、`next step`、`按 boot 开始`、`先看 AGENTS`、`继续当前任务`
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Prefer invoking `$gframework-multi-agent-batch` when the user explicitly wants the main agent to delegate bounded parallel work, track subagent progress, maintain `ai-plan`, verify subagent output, and keep coordinating until reaching a natural stop boundary
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use subagents only when the task is complex, the context is likely to grow too large, or the work can be split into independent parallel subtasks
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use `explorer` subagents for read-only discovery, comparison, tracing, and narrow codebase questions
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use `worker` subagents only for bounded implementation tasks with an explicit file or module ownership boundary
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Keep abstractions projects free of implementation details and engine-specific dependencies
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Preserve existing module boundaries; do not introduce new cross-module dependencies without clear architectural need
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use 4 spaces for indentation; do not use tabs
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Separate logical blocks with blank lines when it improves readability
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Keep line length readable, with around 120 characters as the preferred upper bound
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Public API changes must be covered by unit or integration tests
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Mirror the source structure in test projects whenever practical
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Every user-facing package or module directory that contains a `*.csproj` intended for direct consumption MUST have a sibling `README.md`
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Adding a new top-level module directory without a `README.md` is considered incomplete work
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Governance-only material such as XML audit snapshots, documentation remediation baselines, backlog status, and recovery metadata belongs in `ai-plan/**` or other contributor-only artifacts, not in public docs
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: If a docs category appears in VitePress navigation or sidebar, it MUST have a real landing page or be removed from navigation in the same change
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: `ai-plan/` is split by intent: `ai-plan/public/README.md` for shared startup index, `ai-plan/public/<topic>/todos/` for repository-safe recovery documents, `ai-plan/public/<topic>/traces/` for repository-safe execution traces, `ai-plan/public/<topic>/archive/` for archived stage-level artifacts, `ai-plan/public/archive/<topic>/` for completed-topic archives, and `ai-plan/private/` for worktree-private recovery artifacts
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Use `ai-plan/public/**` only for durable, handoff-safe task state; put temporary notes, local experiments, or worktree-specific scratch recovery data under `ai-plan/private/`
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery document under `ai-plan/public/<topic>/todos/` before making substantive code changes
Learnt from: CR
Repo: GeWuYou/GFramework
Timestamp: 2026-05-09T08:23:08.382Z
Learning: Before considering work complete, confirm required comments and XML docs are present, code follows repository style and naming rules, relevant tests were added or updated, sensitive or unsafe behavior was not introduced, user-facing documentation is updated when needed, and feature adoption docs under `docs/zh-CN/` were added or updated when functionality was added, removed, or refactored
📚 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.Tests/Cqrs/DispatcherZeroPipelineStreamRequest.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherZeroPipelineStreamHandler.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs/Internal/CqrsDispatcher.csGFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.cs
🪛 LanguageTool
.agents/skills/gframework-multi-agent-batch/SKILL.md
[style] ~22-~22: Consider removing “of” to be more concise
Context: ...Use When Adopt this workflow only when all of the following are true: 1. The task is com...
(ALL_OF_THE)
ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md
[uncategorized] ~13-~13: 您的意思是“"不"齐”?
Context: ...E-RP-002 - 当前阶段:Phase 2- 当前焦点: - 已补齐ai-plan/public/README.md` 的 active-to...
(BU)
🔇 Additional comments (18)
ai-plan/public/README.md (1)
24-27: 变更方向正确,入口映射与 active topic 保持一致。
ai-plan-governance的公开入口、追踪文件链接和feat/cqrs-optimization的优先级映射一致,符合当前恢复路径设计。Also applies to: 47-50
ai-plan/public/ai-plan-governance/traces/ai-plan-governance-trace.md (1)
3-43: 追踪文档信息完整,可恢复性良好。本次 trace 已覆盖日期、决策、校验结果和下一步,满足治理主题的恢复与交接要求。
As per coding guidelines, "ai-plan/public/*/traces/**必须记录当前日期、关键决策、验证里程碑与下一步。".agents/skills/gframework-boot/SKILL.md (1)
12-13: 切换策略补充到位,规则边界清晰。在 boot 语境下补充“何时切到 multi-agent-batch”很实用,且与委派策略段落一致。
Based on learnings, “Prefer invoking$gframework-multi-agent-batchwhen the user explicitly wants the main agent to delegate bounded parallel work...”.Also applies to: 50-51
.agents/skills/gframework-batch-boot/SKILL.md (1)
14-16: 入口分流说明清晰,避免了 batch 与 orchestration 场景混用。这里把“重复性批处理”与“主 Agent 持续编排多 worker”边界讲清楚了,方向正确。
Based on learnings, “Use subagents only when the task is complex... or the work can be split into independent parallel subtasks.”Also applies to: 33-33
.agents/skills/gframework-multi-agent-batch/SKILL.md (1)
22-31: 新技能规范完整,职责边界与停止条件定义到位。这份技能文档已经具备实际执行所需的关键约束,尤其是主 Agent 责任和 worker 边界定义。
Based on learnings, “Prefer invoking$gframework-multi-agent-batchwhen the user explicitly wants the main agent to delegate bounded parallel work...”Also applies to: 53-68, 87-98
.agents/skills/README.md (1)
3-3: 公开入口文档更新准确,新增技能可发现性良好。入口总览、适用场景和示例三部分对齐,阅读者可以直接判断何时使用该技能。
Also applies to: 69-91
.agents/skills/gframework-multi-agent-batch/agents/openai.yaml (1)
1-4: 接口配置与技能职责对齐,定义清晰。
default_prompt对主 Agent 责任的约束表达明确,符合该技能定位。ai-plan/public/ai-plan-governance/todos/ai-plan-governance-tracking.md (1)
10-23: tracking 文档满足恢复要求,信息闭环完整。恢复点、风险、验证和下一步都已覆盖,能够支撑后续无缝续作。
As per coding guidelines, "ai-plan/public/*/todos/**必须记录当前阶段、active recovery point、已知风险和下一推荐恢复步骤。"Also applies to: 45-67
AGENTS.md (2)
105-106: 路径更新合理且一致。将技能路径从
.codex/skills/迁移到.agents/skills/符合仓库维护的技能管理策略,两个技能路径更新保持了一致性。
109-111: 描述清晰,与下文协调规则对齐良好。更新后的描述明确了
$gframework-multi-agent-batch的使用场景和主要职责,与新增的"Multi-Agent Coordination Rules"章节形成良好的呼应。"natural stop boundary"这一术语在下文第 167 行的停止条件中有所体现。GFramework.Cqrs/Internal/CqrsDispatcher.cs (2)
29-31: stream 零管道判定缓存补得很到位。把
CreateStream(...)的 behavior presence 判定下沉为 dispatcher 实例级缓存后,零管道 steady-state 不再重复打容器查询,而且和 request 路径保持了同一优化模型。Also applies to: 194-214, 216-229
400-454: 强类型 stream binding / executor 链路拆分得很干净。这里把 binding、invoker、pipeline executor 全部收口到
TResponse维度后,缓存命中路径不再退化成object桥接;同时 generated provider 的适配也被限制在 binding 创建阶段,热路径更清晰。Also applies to: 462-510, 579-1098, 1233-1313
GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs (1)
198-245: 这组回归把 stream 缓存边界锁得很扎实。既覆盖了 dispatcher 实例级 presence cache 的隔离语义,也把新的 typed stream binding / pipeline executor 读取路径一起纳入了断言,和 runtime 改动是对齐的。
Also applies to: 765-790, 808-822, 849-910, 960-984
GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs (1)
225-266: generated stream 缓存复用回归补得很好。这里不仅验证了结果不变,还把 binding 和 pipeline executor 的复用都显式锁住了,能很好地兜住这次 typed stream dispatch 重构。
Also applies to: 1005-1062
GFramework.Cqrs.Benchmarks/Messaging/RequestLifetimeBenchmarks.cs (1)
88-100: benchmark 变量控制做得很清楚。先固定 generated descriptor 宿主,再单独覆盖 handler 生命周期,并在 setup/cleanup 两端清 cache,这样量到的更接近“生命周期差异”本身,而不是历史缓存或注册路径噪音。
Also applies to: 118-125, 160-163
GFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamLifetimeBenchmarkRegistry.cs (1)
26-42: generated lane 的类型隔离保持得不错。descriptor、匹配条件和静态调用桥都一起切到
GeneratedBenchmark*类型后,stream lifetime benchmark 的 generated / reflection 两条路径不会再共用同一组请求响应合同。Also applies to: 81-108
GFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestLifetimeBenchmarkRegistry.cs (1)
1-112: LGTM!
GeneratedRequestLifetimeBenchmarkRegistry作为 hand-written generated registry,接口实现完整、XML 文档齐全;Register(...)仅做参数校验与诊断日志、不在此处注入 handler 生命周期,配合 benchmark 主体显式覆盖Singleton/Transient注册的设计意图清晰;InvokeBenchmarkRequestHandler与 descriptor 元数据维护一致,不引入隐性副作用。GFramework.Cqrs.Benchmarks/Messaging/StreamLifetimeBenchmarks.cs (1)
32-209: LGTM —— 四方口径与双观测维度组织清晰
StreamLifetimeBenchmarks把 reflection / generated 两条 GFramework 路径分别给独立容器与 runtime,再叠加Observation维度统一交给ObserveAsync消费,避免了原来"建流 + 完整枚举"被混在一起的对照口径;Setup/Cleanup中显式调用BenchmarkDispatcherCacheHelper.ClearDispatcherCaches()、按生命周期分别注册 reflection 与 generated handler 的拆分也是合理的实现。
- 更新 AGENTS 多智能体预算术语说明,明确 worker 波次停止边界 - 修复 StreamLifetimeBenchmarks 的取消传播、观测维度注释与枚举器特性写法 - 调整 benchmark README 与 CQRS ai-plan 恢复文档,移除过期 PR 锚点和旧 diff 统计
Summary
Test ResultsDetails
Insights
Fail Rate
build-and-test: Run #1101
🎉 All tests passed!Slowest Tests
± Comparison with run #1100 at 1b93205 | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 46 runs. Github Test Reporter by CTRF 💚 |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Summary by CodeRabbit
发布说明
新功能
文档
测试 / 基准