Reputation: 1425
I know this seems quite obvious for a lot of people but my client is using a pattern that I am not really convenient with.
Case is, that a customer of theirs sends a deposit or withdrawal that through nservicebus is sent to a third party system. The third party system need to take care of that transaction but it might take days, maybe even weeks before the transaction is completed.
The solution today is that a saga is created that first sends a message for putting the transaction over to the third party system. When done, the sagas next step is to check for a completion update. If the transaction isn't completed a requesttimeout is sent, 'like a wait'. When the timeout is reached the same check is performed once again and a new requesttimeout is sent... and so on. This has been an eternal loop. What else that it does is to completely fill ServiceInsight with same SagaTimeout over and over.
I have been looking into SLR but it seems to come out shorthanded. I would only need many retries for a particular message not for all messages.
To add, the third party system cannot send an event of transaction has been completed which means we need to poll for completion updates.
Another, what I believe better solution would be to save the transaction's status, send the transaction to third party and finish this particular saga. Then have a saga that is checking for completion updates using time intervals.
Is it a common pattern to use the sagatimeouts this way? And, is it a better solution to have a saga/handler only checking for completion updates?
Upvotes: 3
Views: 866
Reputation: 18628
IMO it sounds like your saga mixes technical concerns (polling an external service, waiting for something to happen) with domain concerns (wanting to be notified when that thing happened).
My experience is that you can often benefit from isolating your domain stuff from the technical stuff, and in this case it would probably mean that you should put the polling in an integration service somewhere, which would then emit appropriate events when stuff happens.
This way, the saga could have a timeout on the overall process (e.g. to check that the process has finished within four weeks, or whatever you think is the maximum time it must take before anyone) and just subscribe to the TransactionCompleted
event from the integration service.
Upvotes: 0
Reputation: 2531
As far as I can tell, you are doing it the way it's supposed to be done. You could start a separate saga to handle the timeouts of course, but I don't see any good reason to do that.
Since you don't know when the transaction/process will finish on the third party system it can't be very time sensitive for the end user, so you don't need to request timeouts very often. You could even count the number of timeouts in the saga data and increase the timespan for the next timeout so minimize the number of timeouts. You could also check for how long the saga has been running and alert someone (you or the customer etc.) if the third party system has taken "too long" to finish the transaction. This is where NSB sagas really shines, it's really flexible in handling these situations.
And certainly don't use SLR for this kind of thing, it's only meant to retry handlers when an intermittent error occurs.
Upvotes: 3