Re: [rules-users] Reclaiming memory usage
Chris, I haven't tried your code, but just looking at the rule, there is no temporal correlation between DataReading and ReconfigEvent, so if I am not mistaken, that will create a required interval of infinite time when the temporal reasoning is applied, meaning the engine has to keep the readings in memory forever. Adding a temporal constraint on the ReconfigEvent pattern on your rule or defining an explicit expiration policy for the DataReadings are ways to work around that. Edson 2011/7/26 Chris Richmond crichm...@referentia.com Hello I am performing a simple test of injecting an event every 1 millisecond like so: for (int x = 0; x 10; x++){ DataReading dr = new DataReading(Reading + x, 12.0f); myStream.insert(dr); ksession.fireAllRules(); Thread.sleep(1); } The rule that evaluates this is simple. It basically delays then for 3s to see if a followup reading is inserted and makes sure that no ReconfigEvent is active(5s expiration). So if a reading comes in and a followup reading is not inserted within 3 seconds and there is is not an existing ReconfigEvent event alive, then it should output and insert a ReconfigEvent, essentially disabling any DataReading action on those events for the next 5 seconds or so. This all works just fine as expected. My question is, how come I don't get memory back when all 100,000 of my events have been inserted. Memory goes up slowly over the course of insertions, which I can understand, but once that loop is finished, memory never reduces, so essentially, the application will eventually run out of memory after some time. I should not have to explicitly remove/retract events should I? Shouldn't they be removed from working memory as soon as they are no longer viable? What should I be doing to reclaim memory from the session/knowledgebase? I have included the full Main program here and the Sample.drl file below it. FusionMain.java* package com.sample; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseConfiguration; 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.conf.EventProcessingOption; 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; public class FusionMain { @SuppressWarnings(restriction) public static void main(String[] args) { try { KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); config.setOption( ClockTypeOption.get(realtime) ); KnowledgeBase kbase; kbase = readKnowledgeBase(); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); WorkingMemoryEntryPoint myStream = ksession.getWorkingMemoryEntryPoint(My Stream); for (int x = 0; x 10; x++){ DataReading dr = new DataReading(Reading + x, 12.0f); myStream.insert(dr); ksession.fireAllRules(); Thread.sleep(1); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @SuppressWarnings(restriction) 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.); } KnowledgeBaseConfiguration kbConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); kbConfig.setOption( EventProcessingOption.STREAM ); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbConfig); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); return kbase; } } *Sample.drl* package com.sample import java.util.Date; declare DataReading @role( event ) end declare ReconfigEvent @role( event ) @expires ( 5s ) end rule Wait for follup reading or no config //lock-on-active when $dr: DataReading(reading 10.0) from entry-point My Stream not(DataReading(reading 10.0, this after[0s,3s] $dr) from entry-point My Stream) not(ReconfigEvent()
Re: [rules-users] Reclaiming memory usage
Edson, I was under the impression that this: declare ReconfigEvent @role( event ) @expires ( 5s ) end would cover that, meaning that every ReconfigEvent would expire after 5s, thus causing to no longer be needed by the engine. Thanks, Chris On 7/25/2011 12:17 PM, Edson Tirelli wrote: Chris, I haven't tried your code, but just looking at the rule, there is no temporal correlation between DataReading and ReconfigEvent, so if I am not mistaken, that will create a required interval of infinite time when the temporal reasoning is applied, meaning the engine has to keep the readings in memory forever. Adding a temporal constraint on the ReconfigEvent pattern on your rule or defining an explicit expiration policy for the DataReadings are ways to work around that. Edson 2011/7/26 Chris Richmond crichm...@referentia.com mailto:crichm...@referentia.com Hello I am performing a simple test of injecting an event every 1 millisecond like so: for (int x = 0; x 10; x++){ DataReading dr = new DataReading(Reading + x, 12.0f); myStream.insert(dr); ksession.fireAllRules(); Thread.sleep(1); } The rule that evaluates this is simple. It basically delays then for 3s to see if a followup reading is inserted and makes sure that no ReconfigEvent is active(5s expiration). So if a reading comes in and a followup reading is not inserted within 3 seconds and there is is not an existing ReconfigEvent event alive, then it should output and insert a ReconfigEvent, essentially disabling any DataReading action on those events for the next 5 seconds or so. This all works just fine as expected. My question is, how come I don't get memory back when all 100,000 of my events have been inserted. Memory goes up slowly over the course of insertions, which I can understand, but once that loop is finished, memory never reduces, so essentially, the application will eventually run out of memory after some time. I should not have to explicitly remove/retract events should I? Shouldn't they be removed from working memory as soon as they are no longer viable? What should I be doing to reclaim memory from the session/knowledgebase? I have included the full Main program here and the Sample.drl file below it. FusionMain.java* package com.sample; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseConfiguration; 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.conf.EventProcessingOption; 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; public class FusionMain { @SuppressWarnings(restriction) public static void main(String[] args) { try { KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); config.setOption( ClockTypeOption.get(realtime) ); KnowledgeBase kbase; kbase = readKnowledgeBase(); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); WorkingMemoryEntryPoint myStream = ksession.getWorkingMemoryEntryPoint(My Stream); for (int x = 0; x 10; x++){ DataReading dr = new DataReading(Reading + x, 12.0f); myStream.insert(dr); ksession.fireAllRules(); Thread.sleep(1); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @SuppressWarnings(restriction) 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.); } KnowledgeBaseConfiguration kbConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); kbConfig.setOption( EventProcessingOption.STREAM );
Re: [rules-users] Reclaiming memory usage
Chris That defines the expiration policy for ReconfigEvent, but it does not define the relationship between ReconfigEvent and DataReading. Imagine a timeline, dotted with ReconfigEvents... what your rule is saying is for each DataReading event, match it with all the periods where there is no ReconfigEvent, as the lifetime of DataReading is infinity. Maybe a simpler way of understanding it (without using the not for simplification) is think about this: declare Man @livesUpTo( 100 years ) end rule marriage when $w : Woman( age 18 ) $m : Man( ) then // marry woman and man end The rule above defines that each woman will merry every existing man, even if each of them only lives for 100 years. Edson 2011/7/26 Chris Richmond crichm...@referentia.com ** Edson, I was under the impression that this: declare ReconfigEvent @role( event ) @expires ( 5s ) end would cover that, meaning that every ReconfigEvent would expire after 5s, thus causing to no longer be needed by the engine. Thanks, Chris On 7/25/2011 12:17 PM, Edson Tirelli wrote: Chris, I haven't tried your code, but just looking at the rule, there is no temporal correlation between DataReading and ReconfigEvent, so if I am not mistaken, that will create a required interval of infinite time when the temporal reasoning is applied, meaning the engine has to keep the readings in memory forever. Adding a temporal constraint on the ReconfigEvent pattern on your rule or defining an explicit expiration policy for the DataReadings are ways to work around that. Edson 2011/7/26 Chris Richmond crichm...@referentia.com Hello I am performing a simple test of injecting an event every 1 millisecond like so: for (int x = 0; x 10; x++){ DataReading dr = new DataReading(Reading + x, 12.0f); myStream.insert(dr); ksession.fireAllRules(); Thread.sleep(1); } The rule that evaluates this is simple. It basically delays then for 3s to see if a followup reading is inserted and makes sure that no ReconfigEvent is active(5s expiration). So if a reading comes in and a followup reading is not inserted within 3 seconds and there is is not an existing ReconfigEvent event alive, then it should output and insert a ReconfigEvent, essentially disabling any DataReading action on those events for the next 5 seconds or so. This all works just fine as expected. My question is, how come I don't get memory back when all 100,000 of my events have been inserted. Memory goes up slowly over the course of insertions, which I can understand, but once that loop is finished, memory never reduces, so essentially, the application will eventually run out of memory after some time. I should not have to explicitly remove/retract events should I? Shouldn't they be removed from working memory as soon as they are no longer viable? What should I be doing to reclaim memory from the session/knowledgebase? I have included the full Main program here and the Sample.drl file below it. FusionMain.java* package com.sample; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseConfiguration; 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.conf.EventProcessingOption; 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; public class FusionMain { @SuppressWarnings(restriction) public static void main(String[] args) { try { KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); config.setOption( ClockTypeOption.get(realtime) ); KnowledgeBase kbase; kbase = readKnowledgeBase(); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); WorkingMemoryEntryPoint myStream = ksession.getWorkingMemoryEntryPoint(My Stream); for (int x = 0; x 10; x++){ DataReading dr = new DataReading(Reading + x, 12.0f); myStream.insert(dr); ksession.fireAllRules(); Thread.sleep(1); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @SuppressWarnings(restriction) private static KnowledgeBase readKnowledgeBase() throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
Re: [rules-users] Reclaiming memory usage
Ok, well how to make them marry only those alive(100 years old) and ensure all those over 100 years old go out of memory? Chris On 7/25/2011 2:32 PM, Edson Tirelli wrote: Chris That defines the expiration policy for ReconfigEvent, but it does not define the relationship between ReconfigEvent and DataReading. Imagine a timeline, dotted with ReconfigEvents... what your rule is saying is for each DataReading event, match it with all the periods where there is no ReconfigEvent, as the lifetime of DataReading is infinity. Maybe a simpler way of understanding it (without using the not for simplification) is think about this: declare Man @livesUpTo( 100 years ) end rule marriage when $w : Woman( age 18 ) $m : Man( ) then // marry woman and man end The rule above defines that each woman will merry every existing man, even if each of them only lives for 100 years. Edson 2011/7/26 Chris Richmond crichm...@referentia.com mailto:crichm...@referentia.com Edson, I was under the impression that this: declare ReconfigEvent @role( event ) @expires ( 5s ) end would cover that, meaning that every ReconfigEvent would expire after 5s, thus causing to no longer be needed by the engine. Thanks, Chris On 7/25/2011 12:17 PM, Edson Tirelli wrote: Chris, I haven't tried your code, but just looking at the rule, there is no temporal correlation between DataReading and ReconfigEvent, so if I am not mistaken, that will create a required interval of infinite time when the temporal reasoning is applied, meaning the engine has to keep the readings in memory forever. Adding a temporal constraint on the ReconfigEvent pattern on your rule or defining an explicit expiration policy for the DataReadings are ways to work around that. Edson 2011/7/26 Chris Richmond crichm...@referentia.com mailto:crichm...@referentia.com Hello I am performing a simple test of injecting an event every 1 millisecond like so: for (int x = 0; x 10; x++){ DataReading dr = new DataReading(Reading + x, 12.0f); myStream.insert(dr); ksession.fireAllRules(); Thread.sleep(1); } The rule that evaluates this is simple. It basically delays then for 3s to see if a followup reading is inserted and makes sure that no ReconfigEvent is active(5s expiration). So if a reading comes in and a followup reading is not inserted within 3 seconds and there is is not an existing ReconfigEvent event alive, then it should output and insert a ReconfigEvent, essentially disabling any DataReading action on those events for the next 5 seconds or so. This all works just fine as expected. My question is, how come I don't get memory back when all 100,000 of my events have been inserted. Memory goes up slowly over the course of insertions, which I can understand, but once that loop is finished, memory never reduces, so essentially, the application will eventually run out of memory after some time. I should not have to explicitly remove/retract events should I? Shouldn't they be removed from working memory as soon as they are no longer viable? What should I be doing to reclaim memory from the session/knowledgebase? I have included the full Main program here and the Sample.drl file below it. FusionMain.java* package com.sample; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseConfiguration; 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.conf.EventProcessingOption; 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; public class FusionMain { @SuppressWarnings(restriction) public static void main(String[] args) { try { KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); config.setOption(
Re: [rules-users] Reclaiming memory usage
Hi Chris, Best way is to explicitly define the relationship with a temporal constraint (although there are other ways). E.g.: when $dr: DataReading(reading 10.0) from entry-point My Stream not(DataReading(reading 10.0, this after[0s,3s] $dr) from entry-point My Stream) not(ReconfigEvent( this before[0,5s] $dr ) from entry-point My Stream) then As we evolve the product I believe we can add defaults and other types of policies to the system that will allow for other ways to define these relationships, but the system, at the moment, will use strict temporal logic and if no temporal join is defined, it will cross product like it would with non-temporal constraints... and that means keeping everything in memory. Edson 2011/7/26 Chris Richmond crichm...@referentia.com ** Ok, well how to make them marry only those alive(100 years old) and ensure all those over 100 years old go out of memory? Chris On 7/25/2011 2:32 PM, Edson Tirelli wrote: Chris That defines the expiration policy for ReconfigEvent, but it does not define the relationship between ReconfigEvent and DataReading. Imagine a timeline, dotted with ReconfigEvents... what your rule is saying is for each DataReading event, match it with all the periods where there is no ReconfigEvent, as the lifetime of DataReading is infinity. Maybe a simpler way of understanding it (without using the not for simplification) is think about this: declare Man @livesUpTo( 100 years ) end rule marriage when $w : Woman( age 18 ) $m : Man( ) then // marry woman and man end The rule above defines that each woman will merry every existing man, even if each of them only lives for 100 years. Edson 2011/7/26 Chris Richmond crichm...@referentia.com Edson, I was under the impression that this: declare ReconfigEvent @role( event ) @expires ( 5s ) end would cover that, meaning that every ReconfigEvent would expire after 5s, thus causing to no longer be needed by the engine. Thanks, Chris On 7/25/2011 12:17 PM, Edson Tirelli wrote: Chris, I haven't tried your code, but just looking at the rule, there is no temporal correlation between DataReading and ReconfigEvent, so if I am not mistaken, that will create a required interval of infinite time when the temporal reasoning is applied, meaning the engine has to keep the readings in memory forever. Adding a temporal constraint on the ReconfigEvent pattern on your rule or defining an explicit expiration policy for the DataReadings are ways to work around that. Edson 2011/7/26 Chris Richmond crichm...@referentia.com Hello I am performing a simple test of injecting an event every 1 millisecond like so: for (int x = 0; x 10; x++){ DataReading dr = new DataReading(Reading + x, 12.0f); myStream.insert(dr); ksession.fireAllRules(); Thread.sleep(1); } The rule that evaluates this is simple. It basically delays then for 3s to see if a followup reading is inserted and makes sure that no ReconfigEvent is active(5s expiration). So if a reading comes in and a followup reading is not inserted within 3 seconds and there is is not an existing ReconfigEvent event alive, then it should output and insert a ReconfigEvent, essentially disabling any DataReading action on those events for the next 5 seconds or so. This all works just fine as expected. My question is, how come I don't get memory back when all 100,000 of my events have been inserted. Memory goes up slowly over the course of insertions, which I can understand, but once that loop is finished, memory never reduces, so essentially, the application will eventually run out of memory after some time. I should not have to explicitly remove/retract events should I? Shouldn't they be removed from working memory as soon as they are no longer viable? What should I be doing to reclaim memory from the session/knowledgebase? I have included the full Main program here and the Sample.drl file below it. FusionMain.java* package com.sample; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseConfiguration; 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.conf.EventProcessingOption; 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; public class FusionMain {