leveluptor
leveluptor

Reputation: 3242

Lazy GString evaluation while being executed by Eval or GroovyShell

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:

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?

Upvotes: 3

Views: 753

Answers (1)

Steinar
Steinar

Reputation: 5950

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.

Upvotes: 3

Related Questions