Reputation: 4053
[Edited for clairty]
I'm not sure I understand correctly.
Inside the Saga everything should be concise and quick, according to these instructive posts:
That is to say that your saga should have no business logic, and no if-else instructions inside. It should be only an orchestrator, and calling it should be planned to be 'success-oriented' - that is: as much validation as possible should have been done before calling the Saga as possible.
But what about the separate handlers (do you call them "independent handlers"?), those handlers that are not inside a saga? Which of the following is correct for them:
a. Should the NServiceBus message handlers outside a saga always complete quickly, and if there is a time-consuming action pass that on to a thread and complete?
b. Or is it better to "hog" the handler, and that way the NServiceBus "knows" that this message is being used with a heavy toll, and can take action accordingly - i.e. with automatic load balancing, create another instance of the handling process on a different process or even different machine?
What is the correct way to go?
And can you supply some sample code along with your answer, calling a Foo.DoTimeConsumingBar()
method.
Thank you.
Upvotes: 0
Views: 272
Reputation: 2283
@pashute, your statements about Sagas are correct, the should do no work (I/O) and should act as choreographers of long running business processes.
Handlers are supposed to follow SRP Single Responsibility Principle, and that should still keep them lean,even if they are I/O intensive. In the case of I/O intensive operations a distributor/load balancer would help to scale out the load.
Does that make sense?
Upvotes: 1
Reputation: 31750
Inside the Saga everything should be concise and quick.
This statement does not mean anything. What do you mean by concise? What do you mean by quick? The saga will work as quickly as it can within the contraints of the container it's running on.
Should the NServiceBus message handlers outside a saga always complete quickly, and if there is a time-consuming action pass that on to a thread and complete?
Not unless you have built your handler in that way, no. If your message handing process is time consuming, there is no process other than the handler instance which will process the message.
Or is it better to "hog" the handler, and that way the NServiceBus "knows" that this message is being used with a heavy toll, and can take action accordingly - i.e. with automatic load balancing?
When run multithreaded, multiple hander instances will be available to process messages. Each handler instance will still only process a single message, but this can happen concurrently. Because there is a single source of messages, which is the input queue, this provides the "load-balancing" behavior you require.
You are supposed to do everything you can so that there is no business logic inside the Saga.....You should be 'success oriented' doing as many validations as possible before the Saga, so that once you enter the Saga you are expecting to succeed
Yes, sagas should only be concerned with the orchestration of the long running process, not the detail of it.
In light of the above I would modify my answer to one of your original questions:
Should the NServiceBus message handlers outside a saga always complete quickly, and if there is a time-consuming action pass that on to a thread and complete?
I don't see any special need for the handlers to complete quickly. The whole point of the saga is that it will dehydrate to disk if it is not in use, so it's not as if the saga is waiting around taking up memory until the external message handlers complete their work.
Regarding your other quesiton about the load balancing, I believe my answer still stands based on my understanding of the question.
Upvotes: 1