Repository navigation
v7: Handlers, RequestAsync and MaxConcurrency - #114
Merged
Merged
Conversation
ObvsServiceBuilder gains HandleCommand, HandleEvent and HandleRequest, each taking a delegate or an ICommandHandler/IEventHandler/IRequestHandler class. Each message is handled in its own DI scope, with a MessageContext for the service name, the scope's services and publishing or sending further messages. Request handlers' responses are sent back as replies. Handlers start with the host. By default each handles one message at a time, in order; HandlerOptions.MaxConcurrency allows more. A handler that throws is logged with the service and message type, and later messages are still handled. Stopping the host waits for running and queued messages, and cancels running handlers if shutdown runs out of time. Handlers on the wrong side of a service (a command handler on a client, an event handler on a server) or for another service's messages fail at startup with the fix. IServiceBusClient.RequestAsync<TRequest, TResponse> sends a request and returns the first response, or throws TimeoutException, measured on an optional TimeProvider so timeouts can be tested with virtual time. Part of #87. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fourth v7 increment, part of #87 (design, section 4). Targets
v7.API
Behaviour
ICommandHandler<T>,IEventHandler<T>andIRequestHandler<TReq, TResp>classes. A class handler comes from DI if registered there; otherwise it's created with its dependencies.MessageContextexposes the service name, the scope's services,PublishAsyncandSendAsync. A request handler's return value is sent back as the reply.IObservablestream and queues messages in a channel.MaxConcurrencyworkers, 1 by default, take them off the queue in order.MaxConcurrency < 1all fail at startup, with the fix in the message.RequestAsyncis an extension onIServiceBusClient, so it works on any bus, hosted or not. It throwsTimeoutException("No Quote response to GetQuote within …") measured on an optionalTimeProvider, and honours cancellation.Dependencies (core)
Microsoft.Extensions.Logging.Abstractions10.0.13, for logging handler errors.System.Threading.ChannelsandMicrosoft.Bcl.TimeProvider10.0.13, fornet472andnetstandard2.0only, since .NET 10 has both built in.Tests (written first)
Obvs.Tests/Hosting/Handlers/, run on the in-memory transport from v7: Obvs.Testing - in-memory transport and test harness #109. All failed withNotImplementedExceptionfirst.ShouldHandleUpToMaxConcurrencyMessagesAtOncefails (6 ran at once, not 3);ShouldHandleOneMessageAtATimeInOrderByDefaultfails (5 at once, not 1).net472,netstandard2.0andnet10.0, and all 189 unit tests pass.Not in this increment (rest of #87)
CancellationTokenoverloads onIServiceBus's own methods; that changes an interface other code implements.IAsyncEnumerablestreams.Subscribe(async …)(v7: Roslyn analyzers with code fixes for common configuration mistakes #86).🤖 Generated with Claude Code