5

I'm trying to find a good design pattern, or perhaps series of patterns, for injecting error handling and retry handling when getting data from a webservice.

For instance, I have:

do {
 //get the data here
 data = Datagetter.getMyData(request)
 if(data.hasError())
 {
 //handle error
 }
} while(shouldRetry());

And I am trying to figure out a way to inject the mechanism the discovers and deals with any error, as well as the mechanism that handles how retrying works (should I wait? have I retried enough? should I modify a request parameter? etc).

I would guess I am not the first person faced with this, and there is a way to do this I just haven't discovered yet.

I have looked into chain-of-responsibility and strategy as possible solutions, but I can't seem to quite finagle them to work.

asked Jun 22, 2015 at 17:48
2
  • It's basically a promise that will be resolved more than once if required. The promise success callback is only executed if the resource is resolved during any attempt (only once), but the error callback is only called after all attempts fail. Commented Jun 22, 2015 at 19:32
  • You might want to look at Hanmer's Patterns for Fault-tolerant software wiley.com/WileyCDA/WileyTitle/productCd-1118351541.html -- the patterns are generalized (you probably want Rollback, and Limit Retries). They're not OO patterns per se, but they're certainly compatible with JavaScript. Commented Jun 22, 2015 at 20:48

4 Answers 4

1

What language are you using? Depending on the language(synchronious, asynchronious) you will have different solutions.

If it is JavaScript, promise is indeed the way to go. Promises in JavaScript

If it is something like C#, you probably don't want to have a loop like you indicated, because you will be blocking the thread. In that scenario, I would look into setting up queuing system in combination with Command Design Pattern:

rabbitMQ | 0mq

Using queue you can send failed messages into the retry queue and retry them in the order they were submitted, potentially with some delay.

answered Jun 22, 2015 at 20:02
3
  • It's not coincidence ;D World is small :) Commented Jun 22, 2015 at 20:24
  • The language is PHP- so not only is it synchronous, it is not threaded. Fundamentally, blocking is unavoidable without getting into using extra process. The truth is, however, blocking isn't really a problem here... the problem is being able to inject different mechanisms to handle errors and retries... Commented Jun 22, 2015 at 22:20
  • Blocking for single call vs blocking for multiple retries is 2 different issues. If the only problem here is how to inject different error handling, strategy is exactly the pattern you need. You can also try State Pattern - but it's a bit of an overkill, not quite the case you can use it for. The idea that I am trying to suggest from the state pattern is that the objects themselves are aware of the logic that needs to happen when a certain(generic) trigger is called. So as far as your function is concerned, it needs to call object.handleError() method every single time there is an error. Commented Jun 22, 2015 at 22:39
1

There are several things to consider here. It is worth reading up on the HTTP specification, specifically about idempotent rules, and to also consider a RESTful style of webservice interface.

In short, if you implement a webservice with GET or HEAD, then in theory it should be safe to call multiple times with the same parameters, but webservices that are implemented as POST, PUT or DELETE should only be called once, and if they fail then it should not be retried without consideration to the consequences of multiple requests.

The theory is that if you are GET'ing a resource, multiple gets to the same resource should be logically equivilent, and that there are no server state consequences for multiple GET requests for the same resource. If the verb is a PUT, POST or DELETE then it is expected that the request could change the state of the server data, and so multiple / repeat requests are likely to have unwanted side effects.

To handle retries well, requires you to consider the error that occured. Retrying an error caused by a 404 may be handled differently from a tcp timeout error, or a 301 redirect, and to understand what that means in the context of this URL.

answered Jun 22, 2015 at 20:09
1
  • 1
    Handling different types of errors and determining how/when to retry is exactly the problem I am facing. The question is, how can I design a loosely coupled system for these issues? Commented Jun 22, 2015 at 22:22
0

Have you looked into Aspect oriented programming ?

https://en.wikipedia.org/wiki/Aspect-oriented_programming

Maybe it helps ?

An other idea would be to use an abstract factory to return the concrete implementation that you need to handle the error on runtime.

answered Jun 23, 2015 at 20:06
0

I'm afraid you need to code the retrying logic yourself. However, this can be separated from the actual service call by utilizing the Proxy pattern. The RetryingProxy wraps the actual service and implements the error handling and retrying policy you need.

answered Jun 24, 2015 at 19:36

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.