Design Pattern: Do While

Tags: #<Tag:0x00007f386b3f5660>

Problem Statement

Sometimes a user wants to perform some sort of action or activate polling during a certain period of time after another event occurs.

Concept

There are two approaches, each suited for slightly different use cases.

  1. Flag

In this approach a flag is set to ON during the time when events should be processed one way and OFF again after a set time. This is best suited for cases where one wants to change how certain events are processed over a certain period of time.

  1. While

In this approach a while loop is executed in a Rule to periodically execute some code (polling perhaps) until the time is expired. This is best suited for cases where you want to actively perform some action repeadedly during a certain period of time.

Example: 1 Flag

This example uses the Expire binding to turn the Switch OFF after 10 minutes.

Items

Switch Monitor_Sensors { expire="10m,command=OFF" }

...

Rules

rule "Monitor event occured"
when
    // Some event
then
    Monitor_Sensors.sendCommand(ON)
end

rule "Process Sensor Events"
when
    // sensor events
then
    if(Monitor_Sensors.state == ON) {
        // Flag is set
    }
    else {
        // Flag is not set
    }
end

Example: 2 While

See Design Pattern: Looping Timers for a safer way to implement a while loop like this using Timers. Do not use Thread::sleep in a while loop like shown below.

Items

Switch Cancel_Polling // may not be needed, included for completeness

...

Rules

rule "Monitoring event occured"
when
    // Some event
then
    val stopLoop= now.plusMinutes(10)
    while(now.isBefore(stopLoop) && Cancel_Polling.state != OFF){
        // perform polling action
        Thread::sleep(500) // choose an appropriate value
    }
end

Related Design Patterns

9 Likes

Why not more efficiently val end = now.plusMinutes(10)?

Because I was in a hurry and clearly didn’t think it through. :blush:

That is better. Editing the original.

1 Like

This always gave me syntax errors, as “end” is a reserved keyword? I ended up using another name for the variable “end”, then the example works fine.

Thanks, but really I should remove Example 2. You should not have a long running Rule like that. It can be really bad. Use Design Pattern: Looping Timers instead.