Re: [rules-users] order of injected events

2011-07-23 Thread Wolfgang Laun
2011/7/23 Chris Richmond 

> **
> Wolfgang,
>
> Thanks very much for that explanation, it cleared up many questions.
>
> "...If the order of your concurrently arriving events is essential, you may
> have to insert an ordinal as a property..."
>
>
Is "sequence number" a better term for this additional property? Usually it
is not considered necessary, either because (in reality) events never arrive
concurrently (according to the clock providing the timestamps!) or because
it does not matter. It's not an elegant solution: you'll need additional
constraints to achieve firing in order, and you may have to retract or mark
processed events to be able to write s.th.

Event( $ord: ordinal, /* processed == false */ ... )
not Event( ordinal < $ord, /* processed == false */ )

An entirely different approach would be to use a custom Agenda strategy,
processing activiations FIFO. But that would be rather hefty.

There's also the issue of running the engine in a thread of its own
(fireUntilHalt) as opposed to alternate between single insertions and
fireAllRules(). Obviously the latter would guarantee processing in order of
arrival.

All of the aforementioned have their pros and cons - much depends on
circumstances defined by your application.
-W



> Can you expand on this idea or in an general practice for handling real
> time streams of data that need to be processed in order they were injected?
>
> Thanks,
> Chris
>
>
>
>
>
> On 7/21/2011 7:54 PM, Wolfgang Laun wrote:
>
> The insertion of DataReading events happens "instantaneously", without
> Drools regaining "consciousness" in between. So, when the Engine wakes up,
> it finds 20 activations in its agenda, with the same salience. Tie breaking
> is defined to use LIFO.
>
> Running the Engine in real time, these 20 events are indeed concurrently
> from the Engine's point of view, and any order of firings is justified; all
> the more so because your rule contains nothing to prefer a firing of an
> older event.
>
> If the order of your concurrently arriving events is essential, you may
> have to insert an ordinal as a property.
>
> Cheers
> -W
>
> On 22 July 2011 11:07, Chris Richmond  wrote:
>
>> I am running a simple test like so:
>>
>> package com.sample;
>>
>> import org.drools.KnowledgeBase;
>> import org.drools.KnowledgeBaseFactory;
>> import org.drools.builder.KnowledgeBuilder;
>> import org.drools.builder.KnowledgeBuilderError;
>> import org.drools.builder.KnowledgeBuilderErrors;
>> import org.drools.builder.KnowledgeBuilderFactory;
>> import org.drools.builder.ResourceType;
>> import org.drools.io.ResourceFactory;
>> import org.drools.logger.KnowledgeRuntimeLogger;
>> import org.drools.logger.KnowledgeRuntimeLoggerFactory;
>> import org.drools.runtime.KnowledgeSessionConfiguration;
>> import org.drools.runtime.StatefulKnowledgeSession;
>> import org.drools.runtime.conf.ClockTypeOption;
>> import org.drools.runtime.rule.WorkingMemoryEntryPoint;
>>
>> import com.sample.DroolsTest.Message;
>>
>> public class FusionMain {
>>
>>   public static final void main(String[] args) {
>>
>>
>>
>>
>> try {
>>
>>   KnowledgeSessionConfiguration config =
>> KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
>>   config.setOption( ClockTypeOption.get("realtime") );
>>   KnowledgeBase kbase;
>>   kbase = readKnowledgeBase();
>>   final StatefulKnowledgeSession ksession =
>> kbase.newStatefulKnowledgeSession();
>>
>>   WorkingMemoryEntryPoint myStream =
>> ksession.getWorkingMemoryEntryPoint("My Stream");
>>
>>   Thread t = new Thread(new Runnable(){
>>
>> @Override
>> public void run() {
>>   ksession.fireUntilHalt();
>>
>> }
>>
>>   });
>>
>>   t.start();
>>
>>   for (float x = 0.0f; x < 20.0f; x++){
>> DataReading dr = new DataReading("Reading " + x, x);
>> myStream.insert(dr);
>>   }
>>
>>
>> } catch (Exception e) {
>>   // TODO Auto-generated catch block
>>   e.printStackTrace();
>> }
>>
>>   }
>>
>>   private static KnowledgeBase readKnowledgeBase() throws Exception {
>> KnowledgeBuilder kbuilder =
>> KnowledgeBuilderFactory.newKnowledgeBuilder();
>> kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"),
>> ResourceType.DRL);
>> KnowledgeBuilderErrors errors = kbuilder.getErrors();
>> if (errors.size() > 0) {
>>   for (KnowledgeBuilderError error: errors) {
>> System.err.println(error);
>>   }
>>   throw new IllegalArgumentException("Could not parse knowledge.");
>> }
>> KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
>> kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
>> return kbase;
>>   }
>>
>>
>> }
>>
>> With the following rule in the sample.drl file:
>>
>> package com.sample
>> import com.sample.DroolsTest.Message;
>> import java.util.Date;
>>
>> declare DataReading
>> @role( event )
>>
>> end
>>
>> rule "MyGuidedRule"
>> dialect "mvel"
>> when
>>   

Re: [rules-users] order of injected events

2011-07-22 Thread Chris Richmond

Wolfgang,

Thanks very much for that explanation, it cleared up many questions.

"...If the order of your concurrently arriving events is essential, you 
may have to insert an ordinal as a property..."


Can you expand on this idea or in an general practice for handling real 
time streams of data that need to be processed in order they were injected?


Thanks,
Chris




On 7/21/2011 7:54 PM, Wolfgang Laun wrote:
The insertion of DataReading events happens "instantaneously", without 
Drools regaining "consciousness" in between. So, when the Engine wakes 
up, it finds 20 activations in its agenda, with the same salience. Tie 
breaking is defined to use LIFO.


Running the Engine in real time, these 20 events are indeed 
concurrently from the Engine's point of view, and any order of firings 
is justified; all the more so because your rule contains nothing to 
prefer a firing of an older event.


If the order of your concurrently arriving events is essential, you 
may have to insert an ordinal as a property.


Cheers
-W

On 22 July 2011 11:07, Chris Richmond > wrote:


I am running a simple test like so:

package com.sample;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.conf.ClockTypeOption;
import org.drools.runtime.rule.WorkingMemoryEntryPoint;

import com.sample.DroolsTest.Message;

public class FusionMain {

  public static final void main(String[] args) {




try {

  KnowledgeSessionConfiguration config =
KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
  config.setOption( ClockTypeOption.get("realtime") );
  KnowledgeBase kbase;
  kbase = readKnowledgeBase();
  final StatefulKnowledgeSession ksession =
kbase.newStatefulKnowledgeSession();

  WorkingMemoryEntryPoint myStream =
ksession.getWorkingMemoryEntryPoint("My Stream");

  Thread t = new Thread(new Runnable(){

@Override
public void run() {
  ksession.fireUntilHalt();

}

  });

  t.start();

  for (float x = 0.0f; x < 20.0f; x++){
DataReading dr = new DataReading("Reading " + x, x);
myStream.insert(dr);
  }


} catch (Exception e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

  }

  private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"),
ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
  for (KnowledgeBuilderError error: errors) {
System.err.println(error);
  }
  throw new IllegalArgumentException("Could not parse
knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
  }


}

With the following rule in the sample.drl file:

package com.sample
import com.sample.DroolsTest.Message;
import java.util.Date;

declare DataReading
@role( event )

end

rule "MyGuidedRule"
dialect "mvel"
when
$dr: DataReading( reading > "10.0" ) from entry-point "My
Stream"
then
System.err.println("Reading: " +  $dr.name
 + " > 10.0 " +
System.currentTimeMillis());
end

know I am running fireUntilHalt on a seperate thread as you can
see, but
events injected fire rules out of order...in fact almost the exact
opposite order in which they were inserted to the stream every time:

Reading: Reading 19.0 > 10.0 1311325346490
Reading: Reading 18.0 > 10.0 1311325346491
Reading: Reading 17.0 > 10.0 1311325346491
Reading: Reading 16.0 > 10.0 1311325346491
Reading: Reading 15.0 > 10.0 1311325346491
Reading: Reading 14.0 > 10.0 1311325346491
Reading: Reading 13.0 > 10.0 1311325346491
Reading: Reading 12.0 > 10.0 1311325346491
Reading: Reading 11.0 > 10.0 1311325346491

I want to eventually perform temporal reasoning, but how can I expect
that to work if events are not evaluated in the order they were
inserted.

Pe

Re: [rules-users] order of injected events

2011-07-21 Thread Wolfgang Laun
The insertion of DataReading events happens "instantaneously", without
Drools regaining "consciousness" in between. So, when the Engine wakes up,
it finds 20 activations in its agenda, with the same salience. Tie breaking
is defined to use LIFO.

Running the Engine in real time, these 20 events are indeed concurrently
from the Engine's point of view, and any order of firings is justified; all
the more so because your rule contains nothing to prefer a firing of an
older event.

If the order of your concurrently arriving events is essential, you may have
to insert an ordinal as a property.

Cheers
-W

On 22 July 2011 11:07, Chris Richmond  wrote:

> I am running a simple test like so:
>
> package com.sample;
>
> import org.drools.KnowledgeBase;
> import org.drools.KnowledgeBaseFactory;
> import org.drools.builder.KnowledgeBuilder;
> import org.drools.builder.KnowledgeBuilderError;
> import org.drools.builder.KnowledgeBuilderErrors;
> import org.drools.builder.KnowledgeBuilderFactory;
> import org.drools.builder.ResourceType;
> import org.drools.io.ResourceFactory;
> import org.drools.logger.KnowledgeRuntimeLogger;
> import org.drools.logger.KnowledgeRuntimeLoggerFactory;
> import org.drools.runtime.KnowledgeSessionConfiguration;
> import org.drools.runtime.StatefulKnowledgeSession;
> import org.drools.runtime.conf.ClockTypeOption;
> import org.drools.runtime.rule.WorkingMemoryEntryPoint;
>
> import com.sample.DroolsTest.Message;
>
> public class FusionMain {
>
>   public static final void main(String[] args) {
>
>
>
>
> try {
>
>   KnowledgeSessionConfiguration config =
> KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
>   config.setOption( ClockTypeOption.get("realtime") );
>   KnowledgeBase kbase;
>   kbase = readKnowledgeBase();
>   final StatefulKnowledgeSession ksession =
> kbase.newStatefulKnowledgeSession();
>
>   WorkingMemoryEntryPoint myStream =
> ksession.getWorkingMemoryEntryPoint("My Stream");
>
>   Thread t = new Thread(new Runnable(){
>
> @Override
> public void run() {
>   ksession.fireUntilHalt();
>
> }
>
>   });
>
>   t.start();
>
>   for (float x = 0.0f; x < 20.0f; x++){
> DataReading dr = new DataReading("Reading " + x, x);
> myStream.insert(dr);
>   }
>
>
> } catch (Exception e) {
>   // TODO Auto-generated catch block
>   e.printStackTrace();
> }
>
>   }
>
>   private static KnowledgeBase readKnowledgeBase() throws Exception {
> KnowledgeBuilder kbuilder =
> KnowledgeBuilderFactory.newKnowledgeBuilder();
> kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"),
> ResourceType.DRL);
> KnowledgeBuilderErrors errors = kbuilder.getErrors();
> if (errors.size() > 0) {
>   for (KnowledgeBuilderError error: errors) {
> System.err.println(error);
>   }
>   throw new IllegalArgumentException("Could not parse knowledge.");
> }
> KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
> kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
> return kbase;
>   }
>
>
> }
>
> With the following rule in the sample.drl file:
>
> package com.sample
> import com.sample.DroolsTest.Message;
> import java.util.Date;
>
> declare DataReading
> @role( event )
>
> end
>
> rule "MyGuidedRule"
> dialect "mvel"
> when
> $dr: DataReading( reading > "10.0" ) from entry-point "My Stream"
> then
> System.err.println("Reading: " +  $dr.name + " > 10.0 " +
> System.currentTimeMillis());
> end
>
> know I am running fireUntilHalt on a seperate thread as you can see, but
> events injected fire rules out of order...in fact almost the exact
> opposite order in which they were inserted to the stream every time:
>
> Reading: Reading 19.0 > 10.0 1311325346490
> Reading: Reading 18.0 > 10.0 1311325346491
> Reading: Reading 17.0 > 10.0 1311325346491
> Reading: Reading 16.0 > 10.0 1311325346491
> Reading: Reading 15.0 > 10.0 1311325346491
> Reading: Reading 14.0 > 10.0 1311325346491
> Reading: Reading 13.0 > 10.0 1311325346491
> Reading: Reading 12.0 > 10.0 1311325346491
> Reading: Reading 11.0 > 10.0 1311325346491
>
> I want to eventually perform temporal reasoning, but how can I expect
> that to work if events are not evaluated in the order they were inserted.
>
> Perhaps I am setting up my session/kb improperly?
>
> Thanks,
> Chris
> ___
> rules-users mailing list
> rules-users@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
___
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users