用于故障转移的Groovy闭包

时间:2015-02-24 19:25:38

标签: groovy closures fault-tolerance

我有以下课程:

class WidgetClient {
    List<Widget> getAllWidgets() {
        _actuallyGetAllWidgets()
    }

    void saveWidget(Widget w) {
        _actuallySaveWidget(w)
    }

    void deleteWidget(Widget w) {
        _actaullyDeleteWidget(w)
    }
}

此类是Widget Service的客户端访问类。不幸的是,小部件服务不是很可靠,并且由于我无法解释的原因,没有任何可重复性,间歇性地不可用。每当我的代码执行WidgetClient方法之一(因此调用远程Widget服务)时,如果调用产生WidgetServiceMethodUnavailableException,我想重试最多5次。现在我可以这样做非Groovy方式:

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
        }
    }
}

但这是令人讨厌的,更糟糕​​的是,我需要为WidgetClient中的每个方法添加该代码。我想看看我是否可以定义存储此重试逻辑的闭包,然后以某种方式从每个WidgetClient方法内部调用该闭包。类似的东西:

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
        }
    }
}

现在我的WidgetClient看起来像:

class WidgetClient {
    List<Widget> getAllWidgets() {
        faultTolerant(_actuallyGetAllWidgets())
    }

    void saveWidget(Widget w) {
        faultTolerant(_actuallySaveWidget(w))
    }

    void deleteWidget(Widget w) {
        faultTolerant(_actaullyDeleteWidget(w))
    }
}

但是,之前从未编写过我自己的Groovy闭包,我不知道从哪里开始。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您的代码看起来不错,您只需将闭包传递给调用所需方法的faultTolerant()方法:

  class WidgetClient {
    List<Widget> getAllWidgets() {
        faultTolerant{_actuallyGetAllWidgets()}
    }

    void saveWidget(Widget w) {
        faultTolerant{_actuallySaveWidget(w)}
    }

    void deleteWidget(Widget w) {
        faultTolerant{_actaullyDeleteWidget(w)}
    }
}

由于您的faultTolerant方法将Closure作为最终参数,您可以按照我在上面的代码中所示调用它,这将传递给定的闭包(它只调用您的actually*Widget()方法)到faultTolerant方法。