我正在使用GPars的fork / join。当我在调用forkOffChild之后抛出异常时,它会被掩埋。
例如:
def myRecursiveClosure = { boolean top ->
try {
if (!top) {
throw new RuntimeException('child had a problem')
} else {
forkOffChild(false)
}
} catch (Exception exc) {
println 'Exception handled internally'
throw exc
}
}
try {
GParsPool.withPool {
GParsPool.runForkJoin(true, myRecursiveClosure)
}
} catch (Exception exc) {
println 'Exception handled externally'
throw exc
}
在这里,我设置了一个标志,所以我知道闭包是递归调用的。然后,我抛出一个异常,它被“内部”捕获,但重新抛出永远不会被“外部”捕获。所以我不知道分叉的孩子失败了。
我也尝试了异常处理程序,但它似乎也没有被调用。
这是预期的行为,还是我做错了什么?有什么策略可以帮助解决这个问题吗?我不能让孩子默默地失败。
谢谢!
答案 0 :(得分:3)
这里重要的一点是forkOffChild()不会等待孩子运行。它只是安排它执行。所以你不能指望forkOffChild()方法传播来自子节点的异常,因为它们可能在父节点从forkOffChild()方法返回后很久就发生了。
然而,通常情况下,父母对子计算的结果感兴趣,所以它在分叉之后的某个时刻使用getChildrenResults()方法收集结果。这会返回一个计算值列表或重新抛出潜在异常。
此代码段显示了获得预期行为的最小更改:
try {
if (!top) {
throw new RuntimeException('child had a problem')
} else {
forkOffChild(false)
println childrenResults
}
} catch (Exception exc) {
println 'Exception handled internally'
throw exc
}