JBoss.orgCommunity Documentation
Events, from a Drools perspective are just a special type of fact. In this way, we can say that all events are facts, but not all facts are events. In the next few sections the specific differences that characterize an event are presented.
An event is a fact that present a few distinguishing characteristics:
Usually immutables: since, by the previously discussed definition, events are a record of a state change in the application domain, i.e., a record of something that already happened, and the past can not be "changed", events are immutables. This constraint is an important requirement for the development of several optimizations and for the specification of the event lifecycle. This does not mean that the java object representing the object must be immutable. Quite the contrary, the engine does not enforce immutability of the object model, because one of the most common usecases for rules is event data enrichment.
As a best practice, the application is allowed to populate un-populated event attributes (to enrich the event with infered data), but already populated attributes should never be changed.
Strong temporal constraints: rules involving events usually require the correlation of multiple events, specially temporal correlations where events are said to happen at some point in time relative to other events.
Managed lifecycle: due to their immutable nature and the temporal constraints, events usually will only match other events and facts during a limited window of time, making it possible for the engine to manage the lifecycle of the events automatically. In other words, one an event is inserted into the working memory, it is possible for the engine to find out when an event can no longer match other facts and automatically retract it, releasing its associated resources.
Use of sliding windows: since all events have timestamps associated to them, it is possible to define and use sliding windows over them, allowing the creation of rules on aggregations of values over a period of time. Example: average of an event value over 60 minutes.
Drools supports the declaration and usage of events with both semantics: point-in-time events and interval-based events.
A simplistic way to understand the unitification of the semantics is to consider a point-in-time event as an interval-based event whose duration is zero.
To declare a fact type as an event, all it is required is to assign the @role metadata tag to the fact type. The @role metadata tag accepts two possible values:
fact : this is the default, declares that the type is to be handled as a regular fact.
event : declares that the type is to be handled as an event.
For instance, the example bellow is declaring that the fact type StockTick in a stock broker application shall be handled as an event.
Example 2.1. declaring a fact type as an event
import some.package.StockTick declare StockTick @role( event ) end
The same applies to facts declared inline. So, if StockTick was a fact type declared in the DRL itself, instead of a previously existing class, the code would be:
Example 2.2. declaring a fact type and assiging it the event role
declare StockTick @role( event ) datetime : java.util.Date symbol : String price : double end
For more information on type declarations, please check the Rule
Language section of the Drools Expert documentation.
All events have a set of metadata associated to them. Most of the metadata values have defaults that are automatically assigned to each event when they are inserted into the working memory, but it is possible to change the default on an event type basis, using the metadata tags listed bellow.
For the examples, lets assume the user has the following class in the application domain model:
Example 2.3. the VoiceCall fact class
/** * A class that represents a voice call in * a Telecom domain model */ public class VoiceCall { private String originNumber; private String destinationNumber; private Date callDateTime; private long callDuration; // in milliseconds // constructors, getters and setters }
The @role meta data was already discussed in the previous section and is presented here for completeness:
@role( <fact|event> )
It annotates a given fact type as either a regular fact or event. It accepts either "fact" or "event" as a parameter. Default is "fact".
Every event has an associated timestamp assigned to it. By default, the timestamp for a given event is read from the Session Clock and assigned to the event at the time the event is inserted into the working memory. Although, sometimes, the event has the timestamp as one of it's own attributes. In this case, the user may tell the engine to use the timestamp from the event's attribute instead of reading it from the Session Clock.
@timestamp( <attributeName> )
To tell the engine what attribute to use as the source of the event's timestamp, just list the attribute name as a parameter to the @timestamp tag.
Example 2.5. declaring the VoiceCall timestamp attribute
declare VoiceCall @role( event ) @timestamp( callDateTime ) end
Drools supports both event semantics: point-in-time events and interval-based events. A point-in-time event is represented as an interval-based event whose duration is zero. By default, all events have duration zero. The user may attribute a different duration for an event by declaring which attribute in the event type contains the duration of the event.
@duration( <attributeName> )
So, for our VoiceCall fact type, the declaration would be:
Example 2.6. declaring the VoiceCall duration attribute
declare VoiceCall @role( event ) @timestamp( callDateTime ) @duration( callDuration ) end
This tag is only considered when running the engine in STREAM mode. Also, additional discussion on the effects of using this tag is made on the Memory Management section. It is included here for completeness.
Events may be automatically expired after some time in the working memory. Typically this happens when, based on the existing rules in the knowledge base, the event can no longer match and activate any rules. Although, it is possible to explicitly define when an event should expire.
@expires( <timeOffset> )
The value of timeOffset is a temporal interval in the form:
[#d][#h][#m][#s][#[ms]]
Where [ ] means an optional parameter and # means a numeric value.
So, to declare that the VoiceCall facts should be expired after 1 hour and 35 minutes after they are inserted into the working memory, the user would write:
Example 2.7. declaring the expiration offset for the VoiceCall events
declare VoiceCall @role( event ) @timestamp( callDateTime ) @duration( callDuration ) @expires( 1h35m ) end
Reasoning over time requires a reference clock. Just to mention one example, if a rule reasons over the average price of a given stock over the last 60 minutes, how the engine knows what stock price changes happened over the last 60 minutes in order to calculate the average? The obvious response is: by comparing the timestamp of the events with the "current time". How the engine knows what time is now? Again, obviously, by querying the Session Clock.
The session clock implements a strategy pattern, allowing different types of clocks to be plugged and used by the engine. This is very important because the engine may be running in an array of different scenarios that may require different clock implementations. Just to mention a few:
Rules testing: testing always requires a controled environment, and when the tests include rules with temporal constraints, it is necessary to not only control the input rules and facts, but also the flow of time.
Regular execution: usually, when running rules in production, the application will require a real time clock that allows the rules engine to react immediately to the time progression.
Special environments: specific environments may have specific requirements on time control. Cluster environments may require clock synchronization through heart beats, or JEE environments may require the use of an AppServer provided clock, etc.
Rules replay or simulation: to replay scenarios or simulate scenarios it is necessary that the application also controls the flow of time.