{"action":"created","issue":{"url":"https://api.github.com/repos/rebus-org/Rebus/issues/745","repository_url":"https://api.github.com/repos/rebus-org/Rebus","labels_url":"https://api.github.com/repos/rebus-org/Rebus/issues/745/labels{/name}","comments_url":"https://api.github.com/repos/rebus-org/Rebus/issues/745/comments","events_url":"https://api.github.com/repos/rebus-org/Rebus/issues/745/events","html_url":"https://github.com/rebus-org/Rebus/issues/745","id":370562539,"node_id":"MDU6SXNzdWUzNzA1NjI1Mzk=","number":745,"title":"Not all handlers are invoked if there is exception thrown from one of the handlers","user":{"login":"Liero","id":3494407,"node_id":"MDQ6VXNlcjM0OTQ0MDc=","avatar_url":"https://avatars2.githubusercontent.com/u/3494407?v=4","gravatar_id":"","url":"https://api.github.com/users/Liero","html_url":"https://github.com/Liero","followers_url":"https://api.github.com/users/Liero/followers","following_url":"https://api.github.com/users/Liero/following{/other_user}","gists_url":"https://api.github.com/users/Liero/gists{/gist_id}","starred_url":"https://api.github.com/users/Liero/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Liero/subscriptions","organizations_url":"https://api.github.com/users/Liero/orgs","repos_url":"https://api.github.com/users/Liero/repos","events_url":"https://api.github.com/users/Liero/events{/privacy}","received_events_url":"https://api.github.com/users/Liero/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":6,"created_at":"2018-10-16T11:19:14Z","updated_at":"2018-10-26T08:57:28Z","closed_at":"2018-10-16T11:53:47Z","author_association":"CONTRIBUTOR","body":"GIVEN that both Handler1 and Handler2 implements IHandleMessange<MyMessage>\r\nWHEN Handler1 throws exception\r\nTHEN Handler2 is never invoked.\r\n\r\nIs this expected behavior? I guess that handlers should be independent by default.\r\n\r\n\r\nRepo:\r\n\r\n```csharp\r\nusing Microsoft.Extensions.DependencyInjection;\r\nusing Rebus.Bus;\r\nusing Rebus.Handlers;\r\nusing Rebus.Routing.TypeBased;\r\nusing Rebus.ServiceProvider;\r\nusing Rebus.Transport.InMem;\r\nusing System;\r\nusing System.Threading.Tasks;\r\n\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        var services = new ServiceCollection();\r\n        services.AutoRegisterHandlersFromAssemblyOf<Handler1>();\r\n        services.AddRebus(configure => configure\r\n            .Transport(t => t.UseInMemoryTransport(new InMemNetwork(), \"Messages\"))\r\n            .Routing(r => r.TypeBased().MapAssemblyOf<Message1>(\"Messages\")));\r\n\r\n        var provider = services.BuildServiceProvider();\r\n        provider.UseRebus();\r\n\r\n        IBus bus = provider.GetRequiredService<IBus>();\r\n        bus.Send(new Message1()).Wait();\r\n\r\n        Task.Delay(1000).Wait();\r\n    }\r\n}\r\n\r\npublic class Handler1 : IHandleMessages<Message1>\r\n{\r\n    public async Task Handle(Message1 message)\r\n    {\r\n        Console.WriteLine(\"Handler1 invoked\");\r\n        await Task.Delay(10);\r\n        throw new Exception(\"My Custom Exception\");\r\n        Console.WriteLine(\"Handler1 handled\");\r\n    }\r\n}\r\npublic class Handler2 : IHandleMessages<Message1>\r\n{\r\n    public async Task Handle(Message1 message)\r\n    {\r\n        Console.WriteLine(\"Handler2 invoked\");\r\n        await Task.Delay(10);\r\n        Console.WriteLine(\"Handler2 handled\");\r\n    }\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/rebus-org/Rebus/issues/comments/433338186","html_url":"https://github.com/rebus-org/Rebus/issues/745#issuecomment-433338186","issue_url":"https://api.github.com/repos/rebus-org/Rebus/issues/745","id":433338186,"node_id":"MDEyOklzc3VlQ29tbWVudDQzMzMzODE4Ng==","user":{"login":"mookid8000","id":32968,"node_id":"MDQ6VXNlcjMyOTY4","avatar_url":"https://avatars1.githubusercontent.com/u/32968?v=4","gravatar_id":"","url":"https://api.github.com/users/mookid8000","html_url":"https://github.com/mookid8000","followers_url":"https://api.github.com/users/mookid8000/followers","following_url":"https://api.github.com/users/mookid8000/following{/other_user}","gists_url":"https://api.github.com/users/mookid8000/gists{/gist_id}","starred_url":"https://api.github.com/users/mookid8000/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mookid8000/subscriptions","organizations_url":"https://api.github.com/users/mookid8000/orgs","repos_url":"https://api.github.com/users/mookid8000/repos","events_url":"https://api.github.com/users/mookid8000/events{/privacy}","received_events_url":"https://api.github.com/users/mookid8000/received_events","type":"User","site_admin":false},"created_at":"2018-10-26T08:57:28Z","updated_at":"2018-10-26T08:57:28Z","author_association":"MEMBER","body":"> I think rebus (and probably message bus in general) is not suitable choice.\r\n\r\nI think so too.\r\n\r\nA service bus could easily find a place in an event sourced architecture, but I would not use it to do the actual event projection.\r\n\r\nIn event processing, you usually want deterministic dispatch and replay of events, so you can be sure your projections consistently end up in the same state. This puts a requirement on being able to correctly process events in order within a partition of some kind. \r\n\r\nMessage queues are pretty bad at delivering things in order. While most queues are of the FIFO kind, processing messages from a queue is usually done in parallel (either by multiple processes, or by means of enabling some level of parallelism within a consumer), which makes it very susceptible to a slight re-ordering of the messages. And even if you reduce the parallelism to 1, most buses will move failed messages to an error queue, which would mess up the ordering at a grander scale 😁 \r\n\r\nSo, to correctly process events in order in a consistent manner, your best best is probably to read them directly from the event store.\r\n\r\nIn conjunction with CQRS and event sourcing, I could see myself use a service bus to reliably and asynchronously deliver commands. A bus could also be used as a process manager, subscribing to events, correlating them, and then issuing new commands. Or if you wanted to distribute the processing of individual events within a project to multiple workers, because they're computationally intensive and independent of eachother."}}
{"actor":{"display_login":"mookid8000"}}