4

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.

  • 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. – Reactgular Jun 22 '15 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. – Fuhrmanator Jun 22 '15 at 20:48
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.

  • It's not coincidence ;D World is small :) – Alexus Jun 22 '15 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... – MirroredFate Jun 22 '15 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. – Alexus Jun 22 '15 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.

  • 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? – MirroredFate Jun 22 '15 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.

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.