I have the following class:
class WidgetClient {
List<Widget> getAllWidgets() {
_actuallyGetAllWidgets()
}
void saveWidget(Widget w) {
_actuallySaveWidget(w)
}
void deleteWidget(Widget w) {
_actaullyDeleteWidget(w)
}
}
This class is a client access class for a Widget Service. Unfortunately the Widget Service is not very reliable and, for reasons I can't explain, without any sort of reproducibility, is intermittently unavailable. Any time my code executes one of the WidgetClient
methods (hence invoking the remote Widget Service), I would like to retry up to 5 times if the invocation produces a WidgetServiceMethodUnavailableException
. Now I could do this the non-Groovy way like so:
List<Widget> getAllWidgets() {
int maxRetries = 5
int currRetries = 0
while(currRetries <= maxRetries) {
currRetries++
try {
return _actuallyGetAllWidgets()
} catch(WidgetServiceMethodUnavailableException wsmuExc) {
continue
} catch(Throwable t) {
throw t
}
}
}
But that is nasty and worse yet, I need to add that code for each method inside the WidgetClient
. I'd like to see if I could define a closure where this retry logic is stored, and then somehow invoke that closure from inside each WidgetClient
method. Something like:
def faultTolerant = { Closure<T> method ->
int maxRetries = 5
int currRetries = 0
while(currRetries <= maxRetries) {
currRetries++
try {
return method()
} catch(WidgetServiceMethodUnavailableException wsmuExc) {
continue
} catch(Throwable t) {
throw t
}
}
}
Now my WidgetClient
can look like:
class WidgetClient {
List<Widget> getAllWidgets() {
faultTolerant(_actuallyGetAllWidgets())
}
void saveWidget(Widget w) {
faultTolerant(_actuallySaveWidget(w))
}
void deleteWidget(Widget w) {
faultTolerant(_actaullyDeleteWidget(w))
}
}
However, having never written my own Groovy closure before, I have no idea where to start. Any ideas?