For a monitoring system, I need to evaluate custom checks which are represented by boolean expressions. For example, I have a simple pseudocode condition (they can be more complex):
if (webservice is unavailable) and (there are no emails about planned downtime)
If possible, I'd like to use short-circuit evaluation here, so that if webservice is available (and the first condition is false
), the second part won't be evaluated, as the overall result will be false
anyway. Due to this, I can avoid connecting to mail server (and other time-consuming operations) when it's unnecessary.
Here is an example of what I'm trying to achieve:
class WebserviceDownCheck {
boolean check() {
println 'Checking webservice'
return false
}
}
class NoDowntimeEmailCheck {
boolean check() { //shouldn't be executed
println 'Checking emails'
return true
}
}
//using string evaluation, because conditions are constructed during runtime
Eval.me("${new WebserviceDownCheck().check()} && ${new NoDowntimeEmailCheck().check()}")
The output is:
Checking webservice
Checking emails //shouldn't be there
Result: false
NoDowntimeEmailCheck().check()
shouldn't be executed, because the first condition is already false
.
I've tried:
GroovyShell
instead of Eval
check()
methods to fields and applying @Lazy
transformation${new WebserviceDownCheck().check()}
to ${ -> new WebserviceDownCheck().check()}
(saw it here)Seems that I need some lazy mechanism which will allow me to initialize GString
while Eval
(or GroovyShell
) is already executing it. Maybe something like lazy Binding
for GroovyShell
.
I wonder, is it somehow possible without writing custom string evaluation logic?
Combine it into one expression, like this:
Eval.me("${new WebserviceDownCheck().check() && new NoDowntimeEmailCheck().check()}")
and only the first will be evaluated if the result is false.