@@ -36,7 +36,7 @@ public class CoreBenchmarks
3636 private readonly PingCommand _pingCommand = new ( "test-123" ) ;
3737 private readonly GetOrder _getOrder = new ( 42 ) ;
3838 private readonly GetOrderWithDependencies _getOrderWithDependencies = new ( 42 ) ;
39- private readonly GetOrderShortCircuit _getOrderShortCircuit = new ( 42 ) ;
39+ private readonly GetCachedOrder _getCachedOrder = new ( 42 ) ;
4040 private readonly UserRegisteredEvent _userRegisteredEvent = new ( "User-456" , "test@example.com" ) ;
4141 private readonly CreateOrder _createOrder = new ( 123 , 99.99m ) ;
4242
@@ -46,6 +46,7 @@ public class CoreBenchmarks
4646 private readonly MediatorNetGetOrderWithDependencies _mediatorNetGetOrderWithDependencies = new ( 42 ) ;
4747 private readonly MediatorNetUserRegisteredEvent _mediatorNetUserRegisteredEvent = new ( "User-456" , "test@example.com" ) ;
4848 private readonly MediatorNetCreateOrder _mediatorNetCreateOrder = new ( 123 , 99.99m ) ;
49+ private readonly MediatorNetGetCachedOrder _mediatorNetGetCachedOrder = new ( 42 ) ;
4950
5051 [ GlobalSetup ]
5152 public void Setup ( )
@@ -69,6 +70,8 @@ public void Setup()
6970 cfg . RegisterServicesFromAssemblyContaining < CoreBenchmarks > ( ) ;
7071 // Register timing behavior for GetOrderWithDependencies to match Foundatio's middleware
7172 cfg . AddBehavior < MediatR . IPipelineBehavior < GetOrderWithDependencies , Order > , Handlers . MediatR . TimingBehavior < GetOrderWithDependencies , Order > > ( ) ;
73+ // Register short-circuit behavior for GetCachedOrder
74+ cfg . AddBehavior < MediatR . IPipelineBehavior < GetCachedOrder , Order > , Handlers . MediatR . ShortCircuitBehavior > ( ) ;
7275 // Use parallel notification publisher to match Foundatio/MassTransit behavior
7376 cfg . NotificationPublisher = new MediatR . NotificationPublishers . TaskWhenAllPublisher ( ) ;
7477 } ) ;
@@ -88,13 +91,16 @@ public void Setup()
8891 cfg . AddConsumer < Handlers . MassTransit . MassTransitCreateOrderConsumer > ( ) ;
8992 cfg . AddConsumer < Handlers . MassTransit . MassTransitOrderCreatedConsumer1 > ( ) ;
9093 cfg . AddConsumer < Handlers . MassTransit . MassTransitOrderCreatedConsumer2 > ( ) ;
94+ cfg . AddConsumer < Handlers . MassTransit . MassTransitShortCircuitConsumer > ( ) ;
9195 } ) ;
9296 _masstransitServices = masstransitServices . BuildServiceProvider ( ) ;
9397 _masstransitMediator = _masstransitServices . GetRequiredService < MassTransit . Mediator . IMediator > ( ) ;
9498
9599 // Setup Mediator.SourceGenerator (MediatorNet)
96100 var mediatorNetServices = new ServiceCollection ( ) ;
97101 mediatorNetServices . AddSingleton < IOrderService , OrderService > ( ) ;
102+ // Register short-circuit behavior before AddMediator so it's available in the pipeline
103+ mediatorNetServices . AddSingleton < MediatorLib . IPipelineBehavior < MediatorNetGetCachedOrder , Order > , MediatorNetShortCircuitBehavior > ( ) ;
98104 mediatorNetServices . AddMediator ( options =>
99105 {
100106 options . ServiceLifetime = ServiceLifetime . Singleton ;
@@ -119,7 +125,10 @@ public void Setup()
119125 . IncludeType < Handlers . Wolverine . WolverineQueryWithDependenciesHandler > ( )
120126 . IncludeType < Handlers . Wolverine . WolverineCreateOrderHandler > ( )
121127 . IncludeType < Handlers . Wolverine . WolverineOrderCreatedHandler1 > ( )
122- . IncludeType < Handlers . Wolverine . WolverineOrderCreatedHandler2 > ( ) ;
128+ . IncludeType < Handlers . Wolverine . WolverineOrderCreatedHandler2 > ( )
129+ . IncludeType < Handlers . Wolverine . WolverineShortCircuitHandler > ( ) ;
130+ // Register short-circuit middleware for GetCachedOrder
131+ opts . Policies . ForMessagesOfType < GetCachedOrder > ( ) . AddMiddleware ( typeof ( Handlers . Wolverine . WolverineShortCircuitMiddleware ) ) ;
123132 } )
124133 . Build ( ) ;
125134 _wolverineHost . Start ( ) ;
@@ -329,11 +338,37 @@ public async Task<Order> MediatorNet_CascadingMessages()
329338 return await _mediatorNetMediator . Send ( _mediatorNetCreateOrder ) ;
330339 }
331340
332- // Scenario 6: Short-circuit middleware - Foundatio-only feature
333- // Middleware returns cached result, handler is never invoked
341+ // Scenario 6: Short-circuit middleware - returns cached result, handler is never invoked
342+ // Tests the cost of short-circuiting via middleware (caching, validation, auth, etc.)
334343 [ Benchmark ]
335344 public async Task < Order > Foundatio_ShortCircuit ( )
336345 {
337- return await _foundatioMediator . InvokeAsync < Order > ( _getOrderShortCircuit ) ;
346+ return await _foundatioMediator . InvokeAsync < Order > ( _getCachedOrder ) ;
347+ }
348+
349+ [ Benchmark ]
350+ public async Task < Order > MediatR_ShortCircuit ( )
351+ {
352+ return await _mediatrMediator . Send ( _getCachedOrder ) ;
353+ }
354+
355+ [ Benchmark ]
356+ public async Task < Order > MassTransit_ShortCircuit ( )
357+ {
358+ var client = _masstransitMediator . CreateRequestClient < GetCachedOrder > ( ) ;
359+ var response = await client . GetResponse < Order > ( _getCachedOrder ) ;
360+ return response . Message ;
361+ }
362+
363+ [ Benchmark ]
364+ public async Task < Order ? > Wolverine_ShortCircuit ( )
365+ {
366+ return await _wolverineBus . InvokeAsync < Order > ( _getCachedOrder ) ;
367+ }
368+
369+ [ Benchmark ]
370+ public async Task < Order > MediatorNet_ShortCircuit ( )
371+ {
372+ return await _mediatorNetMediator . Send ( _mediatorNetGetCachedOrder ) ;
338373 }
339374}
0 commit comments