@@ -95,6 +95,12 @@ public void Setup()
9595 cfg . AddConsumer < Handlers . MassTransit . MassTransitOrderCreatedConsumer1 > ( ) ;
9696 cfg . AddConsumer < Handlers . MassTransit . MassTransitOrderCreatedConsumer2 > ( ) ;
9797 cfg . AddConsumer < Handlers . MassTransit . MassTransitShortCircuitConsumer > ( ) ;
98+ // Register timing filter for GetFullQuery and short-circuit filter for GetCachedOrder
99+ cfg . ConfigureMediator ( ( context , mcfg ) =>
100+ {
101+ mcfg . UseConsumeFilter ( typeof ( Handlers . MassTransit . MassTransitTimingFilter < > ) , context ) ;
102+ mcfg . UseConsumeFilter ( typeof ( Handlers . MassTransit . MassTransitShortCircuitFilter < > ) , context ) ;
103+ } ) ;
98104 } ) ;
99105 _masstransitServices = masstransitServices . BuildServiceProvider ( ) ;
100106 _masstransitMediator = _masstransitServices . GetRequiredService < MassTransit . Mediator . IMediator > ( ) ;
@@ -104,6 +110,8 @@ public void Setup()
104110 mediatorNetServices . AddSingleton < IOrderService , OrderService > ( ) ;
105111 // Register short-circuit behavior before AddMediator so it's available in the pipeline
106112 mediatorNetServices . AddSingleton < MediatorLib . IPipelineBehavior < MediatorNetGetCachedOrder , Order > , MediatorNetShortCircuitBehavior > ( ) ;
113+ // Register timing behavior for GetFullQuery to match Foundatio's middleware
114+ mediatorNetServices . AddSingleton < MediatorLib . IPipelineBehavior < MediatorNetGetFullQuery , Order > , MediatorNetTimingBehavior > ( ) ;
107115 mediatorNetServices . AddMediator ( options =>
108116 {
109117 options . ServiceLifetime = ServiceLifetime . Singleton ;
@@ -132,6 +140,8 @@ public void Setup()
132140 . IncludeType < Handlers . Wolverine . WolverineShortCircuitHandler > ( ) ;
133141 // Register short-circuit middleware for GetCachedOrder
134142 opts . Policies . ForMessagesOfType < GetCachedOrder > ( ) . AddMiddleware ( typeof ( Handlers . Wolverine . WolverineShortCircuitMiddleware ) ) ;
143+ // Register timing middleware for GetFullQuery to match Foundatio's middleware
144+ opts . Policies . ForMessagesOfType < GetFullQuery > ( ) . AddMiddleware ( typeof ( Handlers . Wolverine . WolverineTimingMiddleware ) ) ;
135145 } )
136146 . Build ( ) ;
137147 _wolverineHost . Start ( ) ;
@@ -157,66 +167,66 @@ public async Task Cleanup()
157167
158168 // Baseline: Direct method calls (no mediator overhead)
159169 [ Benchmark ]
160- public async Task Direct_Command ( )
170+ public ValueTask Direct_Command ( )
161171 {
162- await _directCommandHandler . HandleAsync ( _pingCommand ) ;
172+ return _directCommandHandler . HandleAsync ( _pingCommand ) ;
163173 }
164174
165175 [ Benchmark ]
166- public async Task < Order > Direct_Query ( )
176+ public ValueTask < Order > Direct_Query ( )
167177 {
168- return await _directQueryHandler . HandleAsync ( _getOrder ) ;
178+ return _directQueryHandler . HandleAsync ( _getOrder ) ;
169179 }
170180
171181 [ Benchmark ]
172- public async Task Direct_Publish ( )
182+ public ValueTask Direct_Publish ( )
173183 {
174- await _directEventHandler . HandleAsync ( _userRegisteredEvent ) ;
184+ return _directEventHandler . HandleAsync ( _userRegisteredEvent ) ;
175185 }
176186
177187
178188 // Scenario 1: InvokeAsync without response (Command)
179189 [ Benchmark ]
180- public async Task Foundatio_Command ( )
190+ public ValueTask Foundatio_Command ( )
181191 {
182- await _foundatioMediator . InvokeAsync ( _pingCommand ) ;
192+ return _foundatioMediator . InvokeAsync ( _pingCommand ) ;
183193 }
184194
185195 [ Benchmark ]
186- public async Task MediatR_Command ( )
196+ public Task MediatR_Command ( )
187197 {
188- await _mediatrMediator . Send ( _pingCommand ) ;
198+ return _mediatrMediator . Send ( _pingCommand ) ;
189199 }
190200
191201 [ Benchmark ]
192- public async Task MassTransit_Command ( )
202+ public Task MassTransit_Command ( )
193203 {
194- await _masstransitMediator . Send ( _pingCommand ) ;
204+ return _masstransitMediator . Send ( _pingCommand ) ;
195205 }
196206
197207 [ Benchmark ]
198- public async Task Wolverine_Command ( )
208+ public Task Wolverine_Command ( )
199209 {
200- await _wolverineBus . InvokeAsync ( _pingCommand ) ;
210+ return _wolverineBus . InvokeAsync ( _pingCommand ) ;
201211 }
202212
203213 [ Benchmark ]
204- public async Task MediatorNet_Command ( )
214+ public ValueTask < global :: Mediator . Unit > MediatorNet_Command ( )
205215 {
206- await _mediatorNetMediator . Send ( _mediatorNetPingCommand ) ;
216+ return _mediatorNetMediator . Send ( _mediatorNetPingCommand ) ;
207217 }
208218
209219 // Scenario 2: InvokeAsync<T> (Query)
210220 [ Benchmark ]
211- public async Task < Order > Foundatio_Query ( )
221+ public ValueTask < Order > Foundatio_Query ( )
212222 {
213- return await _foundatioMediator . InvokeAsync < Order > ( _getOrder ) ;
223+ return _foundatioMediator . InvokeAsync < Order > ( _getOrder ) ;
214224 }
215225
216226 [ Benchmark ]
217- public async Task < Order > MediatR_Query ( )
227+ public Task < Order > MediatR_Query ( )
218228 {
219- return await _mediatrMediator . Send ( _getOrder ) ;
229+ return _mediatrMediator . Send ( _getOrder ) ;
220230 }
221231
222232 [ Benchmark ]
@@ -228,46 +238,46 @@ public async Task<Order> MassTransit_Query()
228238 }
229239
230240 [ Benchmark ]
231- public async Task < Order ? > Wolverine_Query ( )
241+ public Task < Order ? > Wolverine_Query ( )
232242 {
233- return await _wolverineBus . InvokeAsync < Order > ( _getOrder ) ;
243+ return _wolverineBus . InvokeAsync < Order ? > ( _getOrder ) ;
234244 }
235245
236246 [ Benchmark ]
237- public async Task < Order > MediatorNet_Query ( )
247+ public ValueTask < Order > MediatorNet_Query ( )
238248 {
239- return await _mediatorNetMediator . Send ( _mediatorNetGetOrder ) ;
249+ return _mediatorNetMediator . Send ( _mediatorNetGetOrder ) ;
240250 }
241251
242252 // Scenario 3: PublishAsync with a single handler
243253 [ Benchmark ]
244- public async Task Foundatio_Publish ( )
254+ public ValueTask Foundatio_Publish ( )
245255 {
246- await _foundatioMediator . PublishAsync ( _userRegisteredEvent ) ;
256+ return _foundatioMediator . PublishAsync ( _userRegisteredEvent ) ;
247257 }
248258
249259 [ Benchmark ]
250- public async Task MediatR_Publish ( )
260+ public Task MediatR_Publish ( )
251261 {
252- await _mediatrMediator . Publish ( _userRegisteredEvent ) ;
262+ return _mediatrMediator . Publish ( _userRegisteredEvent ) ;
253263 }
254264
255265 [ Benchmark ]
256- public async Task MassTransit_Publish ( )
266+ public Task MassTransit_Publish ( )
257267 {
258- await _masstransitMediator . Publish ( _userRegisteredEvent ) ;
268+ return _masstransitMediator . Publish ( _userRegisteredEvent ) ;
259269 }
260270
261271 [ Benchmark ]
262- public async Task Wolverine_Publish ( )
272+ public ValueTask Wolverine_Publish ( )
263273 {
264- await _wolverineBus . PublishAsync ( _userRegisteredEvent ) ;
274+ return _wolverineBus . PublishAsync ( _userRegisteredEvent ) ;
265275 }
266276
267277 [ Benchmark ]
268- public async Task MediatorNet_Publish ( )
278+ public ValueTask MediatorNet_Publish ( )
269279 {
270- await _mediatorNetMediator . Publish ( _mediatorNetUserRegisteredEvent ) ;
280+ return _mediatorNetMediator . Publish ( _mediatorNetUserRegisteredEvent ) ;
271281 }
272282
273283 // Scenario 4: InvokeAsync<T> with DI (Query with dependency injection and middleware)
@@ -288,9 +298,9 @@ public async Task<Order> Direct_FullQuery()
288298 }
289299
290300 [ Benchmark ]
291- public async Task < Order > Foundatio_FullQuery ( )
301+ public ValueTask < Order > Foundatio_FullQuery ( )
292302 {
293- return await _foundatioMediator . InvokeAsync < Order > ( _getFullQuery ) ;
303+ return _foundatioMediator . InvokeAsync < Order > ( _getFullQuery ) ;
294304 }
295305
296306 [ Benchmark ]
@@ -314,25 +324,25 @@ public async Task<Order> MassTransit_FullQuery()
314324 }
315325
316326 [ Benchmark ]
317- public async Task < Order > MediatorNet_FullQuery ( )
327+ public ValueTask < Order > MediatorNet_FullQuery ( )
318328 {
319- return await _mediatorNetMediator . Send ( _mediatorNetGetFullQuery ) ;
329+ return _mediatorNetMediator . Send ( _mediatorNetGetFullQuery ) ;
320330 }
321331
322332 // Scenario 5: Cascading messages - invoke returns result and auto-publishes events to multiple handlers
323333 [ Benchmark ]
324334 public async Task < Order > Direct_CascadingMessages ( )
325335 {
326- var ( order , evt ) = _directCreateOrderHandler . HandleAsync ( _createOrder ) ;
336+ var ( order , evt ) = await _directCreateOrderHandler . HandleAsync ( _createOrder ) ;
327337 await _directOrderCreatedHandler1 . HandleAsync ( evt ) ;
328338 await _directOrderCreatedHandler2 . HandleAsync ( evt ) ;
329339 return order ;
330340 }
331341
332342 [ Benchmark ]
333- public async Task < Order > Foundatio_CascadingMessages ( )
343+ public ValueTask < Order > Foundatio_CascadingMessages ( )
334344 {
335- return await _foundatioMediator . InvokeAsync < Order > ( _createOrder ) ;
345+ return _foundatioMediator . InvokeAsync < Order > ( _createOrder ) ;
336346 }
337347
338348 [ Benchmark ]
@@ -356,26 +366,26 @@ public async Task<Order> MassTransit_CascadingMessages()
356366 }
357367
358368 [ Benchmark ]
359- public async Task < Order > MediatorNet_CascadingMessages ( )
369+ public ValueTask < Order > MediatorNet_CascadingMessages ( )
360370 {
361- return await _mediatorNetMediator . Send ( _mediatorNetCreateOrder ) ;
371+ return _mediatorNetMediator . Send ( _mediatorNetCreateOrder ) ;
362372 }
363373
364374 // Scenario 6: Short-circuit middleware - returns cached result, handler is never invoked
365375 // Tests the cost of short-circuiting via middleware (caching, validation, auth, etc.)
366376 private static readonly Order _cachedOrder = new ( 999 , 49.99m , DateTime . UtcNow ) ;
367377
368378 [ Benchmark ]
369- public Task < Order > Direct_ShortCircuit ( )
379+ public ValueTask < Order > Direct_ShortCircuit ( )
370380 {
371381 // Simulate ShortCircuitMiddleware.Before returning cached result
372- return Task . FromResult ( _cachedOrder ) ;
382+ return ValueTask . FromResult ( _cachedOrder ) ;
373383 }
374384
375385 [ Benchmark ]
376- public async Task < Order > Foundatio_ShortCircuit ( )
386+ public ValueTask < Order > Foundatio_ShortCircuit ( )
377387 {
378- return await _foundatioMediator . InvokeAsync < Order > ( _getCachedOrder ) ;
388+ return _foundatioMediator . InvokeAsync < Order > ( _getCachedOrder ) ;
379389 }
380390
381391 [ Benchmark ]
@@ -399,8 +409,8 @@ public async Task<Order> MassTransit_ShortCircuit()
399409 }
400410
401411 [ Benchmark ]
402- public async Task < Order > MediatorNet_ShortCircuit ( )
412+ public ValueTask < Order > MediatorNet_ShortCircuit ( )
403413 {
404- return await _mediatorNetMediator . Send ( _mediatorNetGetCachedOrder ) ;
414+ return _mediatorNetMediator . Send ( _mediatorNetGetCachedOrder ) ;
405415 }
406416}
0 commit comments