3

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?

Per
  • 1,393
  • 16
  • 28

2 Answers2

3

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.

Trygve
  • 2,445
  • 1
  • 19
  • 23
0

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.

mookid8000
  • 18,258
  • 2
  • 39
  • 63
  • In this case, do you suggest the integration service is nsb saga inside a separate endpoint that basically just handles timeouts/polling? – Trygve Nov 07 '15 at 20:12
  • could be, yes - but maybe it's not necessary to use a saga for it? couldn't the polling be something simple like a `System.Timers.Timer` that polls once in a while and publishes its discoveries as events? – mookid8000 Nov 09 '15 at 07:32
  • It sounds like mookid8000 is suggesting my initial thought, polling outside the initial saga. and Trygve is saying it is correct implemented already. Both will work, yes, but what is really the NServicebus way? My initial thought was that it was no good idea to timeout the saga and initialize a new run over and over again... but maybe that's the way to do it – Per Nov 10 '15 at 20:56
  • IMO and from what Andreas Öhlund said in a speach I attended a few years back, this scenario is exactly what a Saga is meant for. If you choose to use a separate saga to do the timeouts to avoid "polluting" the main saga with a lot of timeouts, that's probably fine. A saga has a lot of advantages over regular batch jobs or even Timers for polling, it is persisted so it would pick up where it left of in case of service restarts. And it doesn't have any issues with process spikes that are typical with batch jobs. There are a lot of presentations of using NSB in integration scenarios online... – Trygve Nov 12 '15 at 14:28