GFramework/GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs
gewuyou 2ac02c1a6f fix(cqrs): 收敛 benchmark review 修复
- 修复 RequestStartupBenchmarks 的 baseline 分组、初始化阶段对齐与 MediatR 重复注册问题
- 新增共享 dispatcher cache helper,并统一 benchmark 宿主的 MediatR logging/license 过滤配置
- 更新 cqrs-rewrite 跟踪与 trace,记录 PR #326 锚点、验证去重和 startup benchmark 的残留运行风险
2026-05-06 11:07:33 +08:00

50 lines
2.3 KiB
C#

// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0
using System;
using System.Reflection;
namespace GFramework.Cqrs.Benchmarks.Messaging;
/// <summary>
/// 提供 benchmark 共享的 dispatcher 静态缓存清理入口。
/// </summary>
/// <remarks>
/// `GFramework.Cqrs` runtime 会把反射绑定与 generated invoker 元数据缓存在静态字段中。
/// benchmark 需要在同一进程内重复比较 cold-start、reflection 与 generated 路径时,
/// 显式清空这些缓存,避免前一组 benchmark 污染后续结果。
/// </remarks>
internal static class BenchmarkDispatcherCacheHelper
{
/// <summary>
/// 清空 dispatcher 上与 benchmark 对照相关的全部静态缓存。
/// </summary>
public static void ClearDispatcherCaches()
{
ClearDispatcherCache("NotificationDispatchBindings");
ClearDispatcherCache("RequestDispatchBindings");
ClearDispatcherCache("StreamDispatchBindings");
ClearDispatcherCache("GeneratedRequestInvokers");
ClearDispatcherCache("GeneratedStreamInvokers");
}
/// <summary>
/// 通过反射定位并清空 dispatcher 的指定缓存字段。
/// </summary>
/// <param name="fieldName">要清理的静态缓存字段名。</param>
/// <exception cref="InvalidOperationException">指定缓存字段不存在、返回空值或未暴露清理方法。</exception>
internal static void ClearDispatcherCache(string fieldName)
{
var field = typeof(GFramework.Cqrs.CqrsRuntimeFactory).Assembly
.GetType("GFramework.Cqrs.Internal.CqrsDispatcher", throwOnError: true)!
.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static)
?? throw new InvalidOperationException($"Missing dispatcher cache field {fieldName}.");
var cache = field.GetValue(null)
?? throw new InvalidOperationException($"Dispatcher cache field {fieldName} returned null.");
var clearMethod = cache.GetType().GetMethod("Clear", BindingFlags.Public | BindingFlags.Instance)
?? throw new InvalidOperationException(
$"Dispatcher cache field {fieldName} does not expose a Clear method.");
_ = clearMethod.Invoke(cache, null);
}
}