【发布时间】:2011-10-28 13:37:31
【问题描述】:
在 Ruby 中,我可以写:
begin
do_something # exception raised
rescue
# handles error
retry # restart from beginning
end
Groovy/Java 中有类似的东西吗?
我找到了this,但也许有更好的?
【问题讨论】:
标签: java ruby exception groovy
在 Ruby 中,我可以写:
begin
do_something # exception raised
rescue
# handles error
retry # restart from beginning
end
Groovy/Java 中有类似的东西吗?
我找到了this,但也许有更好的?
【问题讨论】:
标签: java ruby exception groovy
您可以在 Groovy 中构建自己的辅助方法来封装此重试逻辑。
def retry(int times = 5, Closure errorHandler = {e-> log.warn(e.message,e)}
, Closure body) {
int retries = 0
def exceptions = []
while(retries++ < times) {
try {
return body.call()
} catch(e) {
exceptions << e
errorHandler.call(e)
}
}
throw new MultipleFailureException("Failed after $times retries", exceptions)
}
(假设MultipleFailureException的定义类似于GPars' AsyncException)
那么在代码中,你可以如下使用这个方法。
retry {
errorProneOperation()
}
或者,使用不同的重试次数和错误处理行为:
retry(2, {e-> e.printStackTrace()}) {
errorProneOperation()
}
【讨论】:
IllegalStateException 会使用其中一个异常(第一个?最后一个?很难说)作为其原因,它会更有用,因为你可以看到为什么它失败了。在生产中,我不希望每次尝试失败时都打印堆栈跟踪。如果所有重试都失败了,我只想知道它。
body.call() 之前重置所需的任何资源 - 在这种情况下,默认关闭可能只是 {->}
catch(Exception e) {,那么任何不可恢复的java.lang.Error(或子类)都不会被捕获,并且会立即退出。
我可以建议模仿一下(我不确定retry 的语义):
def retry(handler, c) {
try {
c()
} catch(e) {
handler(e)
retry(handler, c) // restart from beginning
}
}
def handler = {e ->
// handles error
}
retry(handler) {
do_something // exception raised
}
【讨论】:
现在人们会建议您使用ScheduledExecutorService 来实现这种try-catch-retry 功能,因为Thread.sleep() 被认为已过时并且可能对性能不利。我打算通过 cletus 为您指出一个很好的答案,但我一生都找不到它。如果我可以挖掘它,我会更新我的答案。
编辑: 找到它:How to retry function request after a certain time 希望这对您有所帮助。
【讨论】: