Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • using GroovyShell instead of Eval
  • changing check() methods to fields and applying @Lazy transformation
  • changing ${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?

like image 555
leveluptor Avatar asked Dec 01 '25 02:12

leveluptor


1 Answers

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.

like image 194
Steinar Avatar answered Dec 04 '25 01:12

Steinar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!