`
forge
  • 浏览: 22708 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

DroolsFusion文档翻译整理

阅读更多
版权声明:本文可以自由转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
作者:forge(作者的Blog:http://forge.iteye.com)
原文:http://forge.iteye.com/blog/571047


Drools Fusion Features
Fusion 是业务逻辑集成平台(Business Logic Integration Platform)一部分,是一个CEP/ESP引擎。
事件,是指在应用程序域中有意义状态改变的记录
一个复杂事件是简单事件的集合。CEP(Complex Event Processing) 处理复杂事件-从事件云中检测并选择事件,根据选择的事件和他们建立的关系发现他们的关系推理出新的数据。
比如,一系列的巨额提款激发可疑交易事件的发生。一个复杂事件的发生是由一系列简单事件的引导形成的。
ESP(Event Stream Processing) 是更实时(real-time)的大量事件处理。例如,根据时间计算实时平均交易量。
一、事件(Events).
从drools视图来看,事件就是一个特殊的事实(fact)。我们说,所有的事件都是事实,但是所有的事实并不都是事件。
1.事件和事实不同特征:
(1)通常不可变:事件是在应用程序域中状态改变的记录,记录已经发生的事情,可变的事件是没有意义的。
应用程序允许给没有赋值的事件属性赋值,但是已经赋值的属性是不应该被改变的。
(2)强时间约束:规则涉及的事件通常需要多个事件的相互关系,尤其某个事件相对其他事件发生的时间点的时间关系。
(3)可管理的生命周期:由于上两个事件特征的原因,事件通常在一个有限的时间窗(Time Window)匹配事件和事实,
这就让引擎管理事件的生命周期成为可能。一个事件插入working memory,引擎有能力发现一个不在匹配
其他事实的事件,然后自动回收它,释放相关的资源。
(4)滑动窗( sliding windows)的使用:由于所有的事件都有关联的时间戳,可以定义并使用滑动窗,让事件在特定的一段时间有效。


2.事件声明:

import some.package.StockTick

declare StockTick
    @role( event )
end

将一个已有的StockTick(类)事实生命为事件类型
@role 元数据接受2个值:
fact:默认值,声明为常规的事实
event:声明为事件

由于Drools支持在DRL中声明一个事实,可以去掉StockTick(类),还可以这样:
declare StockTick
    @role( event )

    datetime : java.util.Date
    symbol : String
    price : double
end

3.事件元数据
所有的事件都有一个事件元数据集合。当事件插入working memory,事件元数据会自动赋予默认值,我们可以用元数据标签改变他们的默认值。
假设我们有这样的一个实体类:
/**
* 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
}
(1) @timestamp
默认的,当事件插入working memory,会读取(会话时钟)Session Clock的timestamp赋值给事件的startTimestamp。
@timestamp( <attributeName> )  //以毫秒计算

表示把事件的attributeName属性值赋给事件元数据startTimestamp
declare VoiceCall
    @role( event )
    @timestamp( callDateTime )
end

(2) @duration
Drools支持时间点(point-in-time)事件和时间间隔(interval-based)事件,一个时间点事件可以理解为时间间隔为0。默认,所有的事件的持续时间(duration)为0.我们可以通过@duration标签来修改事件的duration属性值。
@duration( <attributeName> )// 以毫秒计算。
表示把事件的attributeName属性值赋给事件元数据duration
declare VoiceCall
    @role( event )
    @timestamp( callDateTime )
end

(3)@expires
这个标签在引擎为Stream模式下才有效。默认的,当一个事件不在匹配(match)事实,激活规则(有活化的规则),事件自动失效(回收).
@expires( <timeOffset> )
显示的定义事件的失效时间。
timeOffset可以是下列形式:
[#d][#h][#m][#s][#[ms]]
[]表示是可选参数

declare VoiceCall
    @role( event )
    @timestamp( callDateTime )
    @duration( callDuration )
    @expires( 1h35m )
end

VoiceCall事件在1小时35分钟后过期。

二、会话时钟(Session Clock)
Drools 5提供2种时钟。默认的是基于系统时间的即时时钟(real time clock)。另一个是虚拟(pseudo clock)时钟,可以手动控制。
1. 即时时钟(Real Time Clock)
虽然Drools默认使用即时时钟,我们仍然可以显示的配置:
KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
config.setOption( ClockTypeOption.get("realtime") );
2. 配置虚拟时钟(Pseudo Clock)
KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
config.setOption( ClockTypeOption.get("pseudo") );
怎样控制虚拟时钟的例子:

KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
conf.setOption( ClockTypeOption.get( "pseudo" ) );
StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession( conf, null );
       
SessionPseudoClock clock = session.getSessionClock();

// then, while inserting facts, advance the clock as necessary:
FactHandle handle1 = session.insert( tick1 );
clock.advanceTime( 10, TimeUnit.SECONDS );
FactHandle handle2 = session.insert( tick2 );
clock.advanceTime( 30, TimeUnit.SECONDS );
FactHandle handle3 = session.insert( tick3 );

新的SessionPseudoClock时间值为0毫秒,new Date(0) 为GMT 1970 年 1 月 1 日 00:00:00 ,
clock.advanceTime( 10, TimeUnit.SECONDS ); SessionPseudoClock时间值+10秒。

三、Entry Points
一个entry point是事实(facts)或者事件(events)进入引擎的入口点。
1.声明Entry Points
rule "authorize withdraw"
when
    WithdrawRequest( $ai : accountId, $am : amount ) from entry-point "ATM Stream"
    CheckingAccount( accountId == $ai, balance > $am )
then
    // authorize withdraw
end
只有账户的余额大于提款请求的金额,规则才被激活
2.使用Entry Points

// create your rulebase and your session as usual
StatefulKnowledgeSession session = ...

// get a reference to the entry point
WorkingMemoryEntryPoint atmStream = session.getWorkingMemoryEntryPoint( "ATM Stream" );

// and start inserting your facts into the entry point
atmStream.insert( aWithdrawRequest );

通常情况下,我们不需要硬编码把事实插入到WorkingMemory中,通过Drools pipeline,
将从JMS或者 其他非java对象的数据源 中获得信息(对象)插入到WorkingMemory。

默认的entry point是"DEFAULT",是事实进入WorkingMemory的入口点。
session.insert(fact)实际上是session.getWorkingMemoryEntryPoint("DEFAULT").insert(fact)。

四、时间推理(Temporal Reasoning)

Drools 实现了由Allen定义的13种时间操作运算

━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
Temporal Operators  ┃         Illustration       ┃   Interpretation
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃    ___x___                 ┃                         
   x before y       ┃               ___y___      ┃  X发生在y之前
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃    ___y___                 ┃                  
   x after  y       ┃               ___x___      ┃  X发生在y之后
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃      ___x___               ┃                  
   x meets y        ┃             ___y___        ┃  x结束时y开始
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃      ___y___               ┃                  
   x metby y        ┃             ___x___        ┃  y结束时x开始
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━ 
                    ┃   ______x______            ┃                  
   x overlaps y     ┃        ______y______       ┃ x开始在y之前,结束在y之后
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃        ______x______       ┃                  
x overlappedby  y   ┃   ______y______            ┃ x开始在y之后,结束在y之前
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃      ___x___               ┃                  
   x starts y       ┃      ______y______         ┃ x和y同时开始,结束在y之前
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃      ______x______         ┃                  
   x startedby  y   ┃      ___y___               ┃ x和y同时开始,结束在y之后
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃          ___x___           ┃                  
   x during y       ┃       ______y______        ┃  x发生在y期间
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃      ______x______         ┃                  
   x includes y     ┃         ___y___            ┃  y发生在x期间
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃             ___x___        ┃                  
   x finishes y     ┃       ______y______        ┃X开始在y之后,同y一起结束
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃       ______x______        ┃                  
   x finishedby y   ┃             ___y___        ┃X开始在y之前,同y一起结束
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
                    ┃       ______x______        ┃                  
   x coincides y    ┃             y              ┃  X和y同时发生
━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━
1.before

$eventA : EventA( this before[ 3m30s, 4m ] $eventB )
也就是:
3m30s <= $eventB.startTimestamp - $eventA.endTimeStamp <= 4m

before操作符的时间间隔距离是可选的:
如果2个值都被定义了,间隔开始于第1个值,结束于第2个值。
如果只有1个值被定义,间隔开始于该值,结束于正无穷大。
如果没有值定义,间隔开始于1毫秒,结束于正无穷大。

时间间隔距离也可以是负数的,例:
$eventA : EventA( this before[ -3m30s, -2m ] $eventB )

注意:当时间间隔第1个值大于第2个值时,引擎会自动的调换他们。

2.After

$eventA : EventA( this after[ 3m30s, 4m ] $eventB )
也就是:
3m30s <= $eventA.startTimestamp - $eventB.endTimeStamp <= 4m

after操作符的时间间隔距离是可选的:
如果2个值都被定义了,间隔开始于第1个值,结束于第2个值。
如果只有1个值被定义,间隔开始于该值,结束于正无穷大。
如果没有值定义,间隔开始于1毫秒,结束于正无穷大。

时间间隔距离也可以是负数的,例:
$eventA : EventA( this after[ -3m30s, -2m ] $eventB )

注意:当时间间隔第1个值大于第2个值时,引擎会自动的调换他们。

3.meets

$eventA : EventA( this meets $eventB )
也就是:
abs( $eventB.startTimestamp - $eventA.endTimestamp ) == 0

meets操作符有1个可选参数

$eventA : EventA( this meets[ 5s ] $eventB )
也就是:
abs( $eventB.startTimestamp - $eventA.endTimestamp) <= 5s

注意:时间间隔不能为负

4.metby

$eventA : EventA( this metby $eventB )
也就是:
abs( $eventA.startTimestamp - $eventB.endTimestamp ) == 0

metby操作符有1个可选参数

$eventA : EventA( this metby[ 5s ] $eventB )
也就是:
abs( $eventA.startTimestamp - $eventB.endTimestamp) <= 5s

注意:时间间隔不能为负

5.overlaps

$eventA : EventA( this overlaps $eventB )
也就是:
$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp

overlaps操作符有1个/2个可选参数

$eventA : EventA( this overlaps[ 5s ] $eventB )
也就是:
$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp &&
0 <= $eventA.endTimestamp - $eventB.startTimestamp <= 5s

$eventA : EventA( this overlaps[ 5s, 10s ] $eventB )
也就是:
$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp &&
5s <= $eventA.endTimestamp - $eventB.startTimestamp <= 10s

6.overlappedby

eventA : EventA( this overlappedby $eventB )
也就是:
$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp

overlappedby操作符有1个/2个可选参数

$eventA : EventA( this overlappedby[ 5s ] $eventB )
也就是:
$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp &&
0 <= $eventB.endTimestamp - $eventA.startTimestamp <= 5s

$eventA : EventA( this overlappedby[ 5s, 10s ] $eventB )
也就是:
$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp &&
5s <= $eventB.endTimestamp - $eventA.startTimestamp <= 10s

7.starts

$eventA : EventA( this starts $eventB )
也就是:
$eventA.startTimestamp == $eventB.startTimestamp &&
$eventA.endTimestamp < $eventB.endTimestamp

starts操作符有1个可选参数

$eventA : EventA( this starts[ 5s ] $eventB )
也就是:
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s &&
$eventA.endTimestamp < $eventB.endTimestamp

注意:时间间隔不能为负

8.startedby

$eventA : EventA( this startedby $eventB )
也就是:
$eventA.startTimestamp == $eventB.startTimestamp &&
$eventA.endTimestamp > $eventB.endTimestamp

starts操作符有1个可选参数

$eventA : EventA( this starts[ 5s ] $eventB )
也就是:
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s &&
$eventA.endTimestamp > $eventB.endTimestamp

注意:时间间隔不能为负

9.during
$eventA : EventA( this during $eventB )
也就是:
$eventB.startTimestamp < $eventA.startTimestamp <= $eventA.endTimestamp < $eventB.endTimestamp

during操作符有1个/2个/4个可选参数

$eventA : EventA( this during[ 5s ] $eventB )
也就是:
0 < $eventA.startTimestamp - $eventB.startTimestamp <= 5s &&
0 < $eventB.endTimestamp - $eventA.endTimestamp <= 5s

$eventA : EventA( this during[ 5s, 10s ] $eventB )
也就是:
5s <= $eventA.startTimestamp - $eventB.startTimestamp <= 10s &&
5s <= $eventB.endTimestamp - $eventA.endTimestamp <= 10s

$eventA : EventA( this during[ 2s, 6s, 4s, 10s ] $eventB )
也就是:
2s <= $eventA.startTimestamp - $eventB.startTimestamp <= 6s &&
4s <= $eventB.endTimestamp - $eventA.endTimestamp <= 10s

10.includes
$eventA : EventA( this includes $eventB )
也就是:
$eventA.startTimestamp < $eventB.startTimestamp <= $eventB.endTimestamp < $eventA.endTimestamp

includes操作符有1个/2个/4个可选参数

$eventA : EventA( this includes[ 5s ] $eventB )
也就是:
0 < $eventB.startTimestamp - $eventA.startTimestamp <= 5s &&
0 < $eventA.endTimestamp - $eventB.endTimestamp <= 5s

$eventA : EventA( this includes[ 5s, 10s ] $eventB )
也就是:
5s <= $eventB.startTimestamp - $eventA.startTimestamp <= 10s &&
5s <= $eventA.endTimestamp - $eventB.endTimestamp <= 10s

$eventA : EventA( this includes[ 2s, 6s, 4s, 10s ] $eventB )
也就是:
2s <= $eventB.startTimestamp - $eventA.startTimestamp <= 6s &&
4s <= $eventA.endTimestamp - $eventB.endTimestamp <= 10s

11.finishes
$eventA : EventA( this finishes $eventB )
也就是:
$eventB.startTimestamp < $eventA.startTimestamp &&
$eventA.endTimestamp == $eventB.endTimestamp

finishes操作符有1个可选参数

$eventA : EventA( this finishes[ 5s ] $eventB )
也就是:
$eventB.startTimestamp < $eventA.startTimestamp &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 5s

注意:时间间隔不能为负

12.finishedby
$eventA : EventA( this finishedby $eventB )
也就是:
$eventA.startTimestamp < $eventB.startTimestamp &&
$eventA.endTimestamp == $eventB.endTimestamp

finishedby操作符有1个可选参数

$eventA : EventA( this finishedby[ 5s ] $eventB )
也就是:
$eventA.startTimestamp < $eventB.startTimestamp &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 5s

注意:时间间隔不能为负
13.coincides

$eventA : EventA( this coincides $eventB )
也就是:
$eventA.startTimestamp ==$eventB.startTimestamp &&
$eventA.endTimestamp == $eventB.endTimestamp

finishedby操作符有1个/2个可选参数

$eventA : EventA( this coincides[15s] $eventB )
也就是:
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 15s &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 15s

$eventA : EventA( this coincides[15s, 10s] $eventB )
也就是:
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 15s &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 10s

注意:时间间隔不能为负

五、事件处理模式(Event Processing Modes)

Drools支持2种事件处理模式:云模式(Cloud Mode)和流模式(Stream Mode)

1.云模式(Cloud Mode)
云(Cloud)处理模式是默认的处理方式。
在云模式下,不会区分事实和事件,都看成是事实。
(1)没有时间的概念。尽管事件在插入引擎被赋予了时间戳,也不能判断该事件“多大了”,因为没有“现在”的概念。滑动窗(sliding windows)基于“现在”的概念,所以在云模式下无法使用。
(2)无序的事件云。由于事件无序,没有自动的生命周期管理,需要像正常的事实一样显示的删除事件。
云模式虽然是默认的执行模式,我们也可以配置它:
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( EventProcessingOption.CLOUD );
等同系统属性配置:
drools.eventProcessingMode = cloud

2.流模式(Stream Mode)

当处理事件流的时候需要选择流处理模式。
在流模式下:
(1) 插入到引擎里的事件必须是时间顺序的。
(2) 引擎强制性的和使用的会话时钟session clock同步。

配置流模式:
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
等同配置系统属性:
drools.eventProcessingMode = stream

使用流(STREAM)模式,引擎有时间流和"现在"的概念(通过读取Session Clock的时间戳),
提供了以下3种支持:
(1) 滑动窗的支持
(2) 自动的时间生命周期管理
(3) 使用消极模式(Negative Patterns)自动的规则延迟

3.会话时钟(Session Clock)在流模式(Stream mode)中的作用

在云模式下,会话时钟只有一个作用,就是给插入到working momery 的事件赋予时间戳的值(如果规则没有定义时间戳属性)
在流模式下,会话时钟负责维护当前时间戳,基于当前的时间戳,引擎根据事件的年龄计算所有时间运算,从多种源同步流,安排未来任务等等。

4.流模式(in Stream Mode)中的消极模式(Negative Patterns)

消极模式在流模式和云模式意义是不同的。
在云模式下,所有的事实和事件都是预先知道的,消极模式立即计算执行
//a rule that activates immediately upon matching
rule "Sound the alarm"
when
    $f : FireDetected( )
    not( SprinklerActivated( ) )
then
    // sound the alarm
end

在流模式下,带有时间约束的消极模式可以要求引擎等待一段时间后激活规则。

//a rule that automatically delays activation due to temporal constraints

rule "Sound the alarm"
when
    $f : FireDetected( )
    not( SprinklerActivated( this after[0s,10s] $f ) )
then
    // sound the alarm
end

六. 滑动窗(Sliding Windows)
滑动窗是一种选择事件范围的方式。
滑动窗有2种实现方式:滑动时间窗(Sliding Time Windows),滑动长度窗(Sliding Length Windows)。
注意:滑动窗只有在引擎为(STREAM)流模式下才是可用的

1.滑动时间窗(Sliding Time Windows)
滑动时间窗(允许我们的规则)仅仅匹配发生在最近X时间单元的事件。
例如,如果只关心最近2分钟的股票行情,模式(pattern)可以这样写:
StockTick() over window:time( 2m )
更复杂的例子:
如果最近10分钟从传感器读来的温度高于最大的临界值,发出警报。
rule "Sound the alarm in case temperature rises above threshold"
when
    TemperatureThreshold( $max : max )
    Number( doubleValue > $max ) from accumulate(
        SensorReading( $temp : temperature ) over window:time( 10m ),
        average( $temp ) )
then
    // sound the alarm
end

2.滑动长度窗(Sliding Length Windows)
滑动长度窗(允许我们的规则)仅仅匹配发生在最近X个的事件。
例如,如果只关心最近10个IBM股票的行情,模式(pattern)可以这样写:
StockTick( company == "IBM" ) over window:length( 10 )
更复杂的例子:
如果最近100次从传感器读来的温度高于最大的临界值,发出警报。
rule "Sound the alarm in case temperature rises above threshold"
when
    TemperatureThreshold( $max : max )
    Number( doubleValue > $max ) from accumulate(
        SensorReading( $temp : temperature ) over window:length( 100 ),
        average( $temp ) )
then
    // sound the alarm
end

七.Knowledgebase分割(Partitioning)
(注意:这是个实验性的特征,将来可能会发生变化)
传统的Rete算法通常一个线程在执行,也是Drools默认的。但是,该算法本身是可平行(化)的。Drools执行的ReteOO算法通过Knowledgebase分割支持粗粒度的平行执行。

当这个选项可用,Knowledgebase分割成若干个独立的区域,然后用线程池通过这些区域传播事实。该实现保证最多有一个线程在给定的一个区域执行。

要点:这个特征只在LHS平行执行可用,不会改变规则激活行为。

1.平行执行在什么时候有益:
(1)多处理器
(2)knowledge session处理大量的事实
(3)规则的LHS计算量大
(4)knowledge base包含数百或者更多的规则
如果以上条件都符合,这个特征可能会提高knowledgebase计算总性能。

2.配置Knowledgebase分割
//enabling multithread evaluation (partitioning)
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( MultithreadEvaluationOption.YES );
等同系统属性配置:
drools.multithreadEvaluation = <true|false>

3.多线程管理
配置线程池:
//setting the maximum number of threads for rule evaluation to 5
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( MaxThreadsOption.get(5) );
等同系统属性配置:
drools.maxThreads = <-1|1..n>
配置默认值是3,负数值表示在Knowledgebase中有多少分区,引擎就会产生多少线程,使用负数值是很危险的。

八.事件的内存管理

要点:自动的事件内存管理只有在引擎为Stream模式下才有效。

引擎在Steam模式下的好处之一是引擎能够根据时间约束检测出不再匹配任何规则的事件,然后引擎可以没有负作用的安全地回收事件并释放其相关的资源。
引擎有2种基本方式计算一个事件有效期:
(1)显式,使用过期(expiration)策略
(2)隐式,分析事件的时间约束

1.显式的过期偏移量(有效期)
//explicitly defining an expiration offset of 30 minutes for StockTick events
declare StockTick
    @expires( 30m )
end
当StockTick事件持续30分钟后,如果没有规则需要该事件,引擎将自动的回收该事件。

2.推知的过期偏移量

//example rule with temporal constraints
rule "correlate orders"
when
    $bo : BuyOrderEvent( $id : id )
    $ae : AckEvent( id == $id, this after[0,10s] $bo )
then
    // do something
end

引擎需要保存BuyOrderEvent 10秒以匹配AckEvent。
BuyOrderEvent隐式的过期偏移量是10秒,AckEvent隐式的过期偏移量是0。

引擎会分析整个Knowledgebase,找出每个事件类型的过期偏移量。当隐式过期偏移量和显式过期偏移量冲突时,引擎会选择2个值中最大的1个

2
0
分享到:
评论
1 楼 di1984HIT 2014-09-22  
学习了,很好啊~

相关推荐

    基于jsp+servlet+mysql的javaweb健身房俱乐部系统

    包括系统管理后台和前端动态网页的设计搭建。系统管理后台提供给俱乐部员工使用,可以对俱乐部的课程、器材、房间等进行管理维护;前端网页主要提供给消费者使用,可以在线浏览课程、预约上课等。 技术栈:JavaScript,Mysql 数据库,JSP、tomcat、HTML、CSS。

    Tomcat安装配置基础详细教程讲解.docx

    tomcat安装及配置教程 Tomcat安装配置基础详细教程讲解.docx

    51单片机智能百叶窗项目

    51单片机智能百叶窗项目

    PHP课程网站络管理系统

    PHP课程网站络管理系统

    2023年上半年度TikTok行业白皮书电子版.zip

    2023年上半年度TikTok行业白皮书电子版.zip

    扩展卡尔曼滤波算法的python代码实现与解读.docx

    卡尔曼滤波算法 扩展卡尔曼滤波(Extended Kalman Filter, EKF)是卡尔曼滤波的一种扩展,用于解决非线性系统的状态估计问题。EKF通过局部线性化非线性函数来近似非线性系统的行为,从而应用标准的卡尔曼滤波算法。下面是一个简单的扩展卡尔曼滤波算法的Python实现示例,以及对其核心步骤的解读。 ### Python代码实现 ```python import numpy as np def ekf(x, P, measurement_func, measurement_jacobian, control_input=None, control_jacobian=None, measurement=None, R=None, Q=None): """ 扩展卡尔曼滤波算法实现 参数: x: 上一时刻的状态估计值,维度为(n,)的np.array P: 上一时刻的协方差矩阵,维度为(n,n)的np.array measurement_func: 非线性测量模型函数,输入状态输出测量值 measureme

    tomcat安装及配置教程

    tomcat安装及配置教程

    《2022_电商出海营销白皮书》.zip

    《2022_电商出海营销白皮书》.zip

    Python课设-学生信息管理系统

    Python课设-学生信息管理系统

    产品设计塑胶类螺丝柱设计标准,适合新手使用

    适合塑胶类产品设计:内容1:自攻螺丝塑胶孔设计,塑胶螺丝孔设计尺寸要求,十二种经典的螺栓防松设计,螺纹及螺纹连接件 ,螺丝柱设计,螺丝制作工艺及设计准则详述.,螺丝与塑胶柱的基本设计要求,螺丝设计选用规范,螺丝设计标准解析,螺丝孔设计标准,螺丝及塑胶螺丝柱的设计.,螺丝标准,螺丝柱设计,等

    QT实时数据曲线Plot

    1、QT界面布局学习 2、Custom Plot组件学习 3、Custom Plot组件示例 4、Custom Plot组件二次开发

    基于uni-app的垃圾分类精灵的设计与实现源码.zip

    提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

    TikTok直播运营分享1_20231126105338.zip

    TikTok直播运营分享1_20231126105338.zip

    CANON打印机清零软件合集

    目前为止几乎包含 Service Tool 工具的所有版本,支持CANON目前为止的所有型号

    FPGA Verilog PLL锁相环 FIFO同步 ip核调用 仿真工程

    FPGA Verilog PLL锁相环 FIFO同步 ip核调用 仿真工程 FPGA(Field-Programmable Gate Array)是一种可编程逻辑器件,允许用户根据设计需求配置其内部逻辑。在FPGA中,Verilog是一种硬件描述语言,用于编写数字电路的逻辑设计。PLL(Phase-Locked Loop)是FPGA中常用的一种频率合成技术,它通过锁定相位来同步不同信号源,常用于时钟管理和频率分频。 锁相环(PLL)在Verilog中实现通常包括电压控制振荡器(VCO)、分频器、鉴相器和低通滤波器等模块。PLL设计的关键在于调整这些模块参数,以达到所需的输出频率和相位关系。 FIFO(First-In-First-Out)是一种常用的存储结构,用于在不同时钟域之间传递数据,解决时钟域间的同步问题。在FPGA设计中,FIFO的Verilog实现会涉及到读写指针管理和深度控制,确保数据的正确存取。 在FPGA设计中,经常需要调用预定义的IP(Intellectual Property)核,如PLL和FIFO IP,这些核由供应商提供,经过验证,可以直接集成到设计中。

    《2023_TikTok_for_Business_社群电商爆品营销白皮书》.zip

    《2023_TikTok_for_Business_社群电商爆品营销白皮书》.zip

    高校思想政治理论课教师研究专项教学方法改革择优推广项目.doc

    高校思想政治理论课教师研究专项教学方法改革择优推广项目.doc

    《2023年度TikTok电商行业趋势白皮书》.zip

    《2023年度TikTok电商行业趋势白皮书》.zip

    Lab-Electronic Craft Practicum-2-Simulation of a Single Tube Com

    Lab-Electronic Craft Practicum-2-Simulation of a Single Tube Common Emitter Amplifier Circuit //Multisim14.0 //电子工艺实习-2-单管共射极放大电路的仿真

    基于Java的在线作业提交批改系统设计与实现源码.zip

    提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

Global site tag (gtag.js) - Google Analytics