Difference between @duration and @expires in Drools

Viewed 197

I don't fully understand the difference between the @duration and @expires metadata tags for events in Drools. Can someone clarify this?

1 Answers

An event's duration is how long the event takes. Its expiration is when it is removed from working memory.

The easiest way to think of this is to relate them to the real-world concepts. A real world "event" (for example, a meeting) has a certain duration (eg. 1 hour.) Its expiration would be the time it "fell off" your calendar. If you're modeling your calendar, the meeting event's expiration would be that point at which we no longer care about it anymore, maybe after the day or the work week has passed.

The reason for this distinction is because the temporal operators allow us to write rules for conditions based on events that occur at the same time. Since events are not instantaneous (eg. they have a duration when you're not using point-in-time events) they can overlap in a variety of ways. Once the event expires, it is removed from working memory, and subsequent events and rule executions cannot consider that expired event any longer.


Here's an example. Let's say we're building an application where a user has 3 attempts to enter a passcode. After each failed attempt, there is a 3 minute cool down period before they are allowed to try again. If the user has 3 failed login attempts in a 30 minute period, they're locked out; after those 30 minutes are up we don't care about the event anymore and can discard it.

For this use case, we'll name our event AccessDisallowed. It has a duration of 3 minutes, since that is the amount of time that it is "active". It has an expiration of 30 minutes, because the lock-out is only triggered within a 30 minute window.

declare AccessDisallowed
  @duration( cooldownTime ) // property holding the duration, 3 minutes
  @expires( 30m )
end

Then we can write rules that leverage the duration and expiration of these events. In these example rules I'm just going to print messages; in a real system the side effects might include alerting a security system, or locking a user's record in a database.

rule "Disallow access for 3 minutes after Access Disabled"
when
  $lockoutPd: AccessDisallowed()
  PasscodeEntry( this during $lockoutPd )
then
  System.out.println("Passcode entry detected during lockout period.");
end

rule "Lock account after 3 Access Disables"
when
  List( size >= 3 ) from accumulate( $a: AccessDisallowed(), collectList($a) )
then
  System.out.println("3+ login attempts within 30m detected");
end

The first rule is straight forward. When a PasscodeEntry event is received, we check to see if there is an AccessDisallowed event currently in progress. If there is, we respond accordingly. This leverages the duration.

The second rule leverages the expiration. If there are 3 login attempts within a 30 minute window, we lock the account. In this case, we take advantage of the fact that after 30 minutes, the AccessDisallowed event expires and is removed from working memory; thus if there are ever 3 AccessDisallowed events in working memory, it stands to reason they were all put there within the past 30 minutes.

(In a real-world application, we might use sliding windows or the temporal after operator with an accumulator to detect the last condition, since we might need to do other work on the actual events in question.)

Related