Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Sergiy Nikolayev
    @snikolayev
    @Entropy0 I wouldn’t characterize it as an “issue” with GC, but just as how it works. It collects the objects, it just doesn’t immediately return the memory to the OS. If there was memory pressure in the system I’m sure it would shrink the working set. And yes, if you allocate more objects that memory is available for them.
    wangadeketan
    @wangadeketan

    @snikolayev

    @wangadeketan definitely releasing new version this year. Hopefully much sooner than the EOY

    Any update ?

    4 replies
    Sergiy Nikolayev
    @snikolayev
    NRules 0.9.1 is out! See release notes for details: https://github.com/NRules/NRules/releases/v0.9.1
    larrybehaviorlanguage
    @larrybehaviorlanguage
    @snikolayev Congratulations on the release! Just a heads up that we happened to come across this issue purely by accident. I managed to repro it in a unit test in the NRules project, which I included in the ticket: NRules/NRules#246.
    When we first found it, our Or clauses were spread across multiple Or blocks deeply nested within Ands and Ors, but it turns out that I was able to repro the issue without any nesting at all.
    Sergiy Nikolayev
    @snikolayev
    Hi @larrybehaviorlanguage - thanks for a repro scenario - I can see the behavior you are describing in the repro test you created. I'm looking into this. I'll let you know what I find.
    larrybehaviorlanguage
    @larrybehaviorlanguage
    @snikolayev Great, thank you. The last point regarding “ Adding a call to a boolean-returning method at the end of the second clause's final test” threw me because I was adding methods like this in for debug logging and they suppressed the problem!
    Sergiy Nikolayev
    @snikolayev
    @larrybehaviorlanguage it appears this bug has been there for a while (I was worried that 0.9.1 introduced it). The issue is with expression comparison for node sharing, where you have two facts of the same type, and the expressions are literally identical, other than joining to different instances of the same fact. The expression comparison fails to distinguish them, and erroneously shares the nodes believing the expressions rf => rf.ReferenceB == myNameFact and rf => rf.ReferenceB == otherNameFact are the same. The reason the issue goes away as soon as you change or add expressions, is that the opportunity for node sharing goes away. I'm working on fixing it.
    larrybehaviorlanguage
    @larrybehaviorlanguage
    @snikolayev Gotcha. Glad you're able to track it down. Hope the fix isn't too bad.
    Sergiy Nikolayev
    @snikolayev
    @larrybehaviorlanguage FYI I fixed it in develop branch
    larrybehaviorlanguage
    @larrybehaviorlanguage
    @snikolayev That fixed our issue, thanks very much!
    Suman S
    @sumankpm_twitter
    Hi, Since i have license issue's with Visual studio at present. I'm trying out NRules (Rule engine) sample in Visual studio code. How do install the NRules package in Termial ???
    wangadeketan
    @wangadeketan
    Hi @snikolayev ,
    I want to implement one simple rule which will check logger level according to their environment like development, production.
    How can I achieve this using Nrules.
    Sergiy Nikolayev
    @snikolayev
    @wangadeketan it sounds a bit odd to me to look at log level of environment name in business rules. In any case, one option is to insert these concepts as facts into the session.
    wangadeketan
    @wangadeketan
    @snikolayev, Thanks for response.
    I think I have not properly mention my question.
    I am writing one rule which will check log level according to their environment like for development log level is debug and for production log level must be Error.
    I need you guidance how can I can I write this type of rule because their is no database model so how can I execute match and when condition.
    Sergiy Nikolayev
    @snikolayev
    @wangadeketan I'll just say that IMO it seems wrong to do something in the business rules based on what log level is currently enabled. With that caveat, I obviously don't know your circumstances, so if you must do it, here is an example with log4net:
        public class LogLevelRule : Rule
        {
            public static ILog Log = LogManager.GetLogger("MyLogger");
    
            public override void Define()
            {
                string logLevel = default;
    
                When()
                    .Query(() => logLevel, q => q
                        .From(() => GetCurrentLogLevel(Log)));
    
                Then()
                    .Do(x => Console.WriteLine($"Logging at {logLevel} with {Log.Logger.Name}"));
            }
    
            private string GetCurrentLogLevel(ILog logger)
            {
                if(logger.IsDebugEnabled)
                    return "Debug";
                if(logger.IsInfoEnabled)
                    return "Info";
                if(logger.IsWarnEnabled)
                    return "Warn";
                if(logger.IsErrorEnabled)
                    return "Error";
                if(logger.IsFatalEnabled)
                    return "Fatal";
                return "None";
            }
        }
    wangadeketan
    @wangadeketan
    @snikolayev Thanks for quick response
    Huzaif Abdul-Sattar
    @zaifworks
    First, Thanks for building and maintaining a great product.
    Huzaif Abdul-Sattar
    @zaifworks

    We are planning on using NRules as an engine in a multi-tenant environment. As such, we would like to keep the rules repo (and the associated factories) separated. In the same process.

    We would setup a dictionary of tenants and their associated rules repo/factory. When a fact is generated in the app, it would pass it to the process. We will search the dictionary for the tenant. We would then use the factory returned for the tenant to setup a session and process the fact.

    Do you guys think there are any problems with this design?

    3 replies
    Sergiy Nikolayev
    @snikolayev
    The next release of NRules will no longer target .net framework 4.5 or .net standard 1.0. It will target .net standard 2.0 and .net standard 2.1. Given .net standard version compatibility chart this will allow NRules to be used from applications targeting .net framework 4.6.1+, .net core 2.0+ and .net 5. I'm still debating whether to target .net 5 directly - it does not seem to provide any immediate benefit.
    I just wanted to let everyone know ahead of time. Please let me know if there are any concerns with dropping the support of the lower framework versions.
    TAHerman71
    @TAHerman71
    I have a project I am working on where I need to implement some pattern matching (a rule engine, if you will). I have been conducting a bit of research and slogging through several large documents describing various algorithms. Rete is the one I am leaning towards, which eventually lead me to your excellent library. In it's current form, based on my needs, I don't know that I can use your library (unfortunately) but at is helping me conceptualize some things. I was wondering if I could pick your brain for a moment.
    TAHerman71
    @TAHerman71
    I saw an earlier comment that touched on this, but in my case, the working memory elements (WME from now on) are coming from events that the larger application is firing. The short version is that when some system event occurs, it is caught, packed up into an object and sent for processing. This could happen multiple times a second. My thinking is that this object will be what makes up the working memory. This is where I feel I start moving away from the traditions of Rete and I was curious if it makes sense. Since the data is coming from an event, and events are time sensitive, it needs to be processed once (quickly) which means my working memory is more volatile. It feels like the object should enter the working memory, then immediately get sent to the root node and go through the tree as far as it can, triggering a rule if possible. The data entering the WME will always be the same class although it uses a ExpandoObject to hold its specific properties (which may differ across events). I was learning towards using the type of the event as the "ObjectTypeNode". In most cases, the actions executed by the rules will not add anything to working memory. I have an edge case that might do it but I haven't decided yet. Does this make any sense to you? These thesis documents are starting to hurt my brain and I'm worried I'm approaching it incorrectly.
    3 replies
    Duane Kord
    @duanekord

    We have a few hundred rules and we are logging RuleFired, RuleFiring, and others. We are logging everything and it is overwhelming, with thousands of events being captured. I am trying to see if there is a way that I could write some logic that captures the rules that fired for each session, captures the rule/rule info in an object, and after the last rule for that session runs can send that log.

    Is there a way to tell when the rules sessions has started and is complete and will no longer be called until the next session?

    1 reply
    Sergiy Nikolayev
    @snikolayev
    NRules 0.9.2 is out. See release notes for details https://github.com/NRules/NRules/releases/v0.9.2
    Kirk Marple
    @kirk-marple

    Hi all, just getting started with NRules, and we're planning on using it as a constraint mechanism; basically a bunch of rules accept the same input, and I want to get a true/false that all succeeded, or find out that some rule failed. So, it's less about having side effects executed by each rule, but using the rules as a gatekeeper for the next logic I want to execute.

    A naive approach would be to use Match to find data which does not fit the rule, and use Do to throw an exception. When I catch the exception, I can log it and return 'false'.

    Obviously this isn't the optimal use of exceptions for logic, and I wanted to ask if there's a better approach I'm missing? I was looking for a way to pass back some state from each rule, and check this via the session after it had fired. Is that possible?

    If we added a 'results' fact to the session, and poke success/failure in there (i.e. Dictionary<string, bool>, keyed by rule name), is that reasonable solution, given the way NRules works?
    2 replies
    Sergiy Nikolayev
    @snikolayev
    FYI, I enabled discussions on NRules GitHub repo (https://github.com/NRules/NRules/discussions). Gitter channel is still a great venue to get answers to your questions, and I have no intention to discontinue it, but also consider GitHub discussions for questions and conversations that are likely to result in a feature request or a bug report.
    Also, NRules users google group (https://groups.google.com/g/nrules-users) is now retired in favor of GitHub discussions.
    Edvard Pitka
    @epitka
    Is there a section on how to test rules? I am sure it is probably as testing any other code, but still would be nice to have a sample with tests for somebody that is trying to learn NRules.
    Sergiy Nikolayev
    @snikolayev
    @epitka good question. There is a section on the wiki now - I just dropped in a page on unit testing the rules: https://github.com/NRules/NRules/wiki/Unit-Testing-Rules
    You can also look at the NRules integration tests on the GitHub for more examples.
    prashanthvijayakumar
    @prashanthvijayakumar
    Hi. When 2 rules have same priority, and my condition matches both the rules, is there a way I can fire actions for both of them? Currently I am seeing only the highest priority one is being fired.
    6 replies
    Sergiy Nikolayev
    @snikolayev
    I started a spike on serializing rules to/reading from JSON, and created a discussion around that to gauge the interest around this feature. Feel free to comment, send suggestions, try it out, etc. https://github.com/NRules/NRules/discussions/261
    Edvard Pitka
    @epitka
    Are async operations possible in NRules?
    1 reply
    sasannikookar
    @sasannikookar
    Hi all, just getting started with NRules and I have two questions: 1) Is it possible to define (or load) rules (e.g the part under the When() section in the Define method of a rule class) from an external file (e.g. text file)? We have some rules that we need to apply changes to them a lot (e.g. percentage of discount or the calculation formula of payment). 2) As I understood, the NRules works based on the loaded object data in memory. Is it possible to run rules on data in a database? We have a lot of rules in our database that forced us to write these rules in stored procedures. I was wondering if it is possible to bring these rules outside the SP and keep it in the middle or data layers, but we cannot load all the data (different tables) in the memory to run rules on them.
    3 replies
    epouliquen
    @epouliquen

    Hi,

    we are very interested in NRules possibilities, but our use case is very special and I would like your point of view on what is possible or not.

    We are developing a Unity3D app on iOS. This app is consuming data produced by visual editors running on Windows desktop.
    We would like to use power of rules engine mechanism, and be able to design rules on windows, and use them in the iOS app.

    We have tried to use directly rules engines on the ios but of course we hit the 'compile' limitation for code generation on the type of aot platforms.

    My question is : could we eventually think about split NRules behavior in two steps :

    on windows use it to compile rules and get a factory
    then find a way to serialize this factory instance (as dylib ?), put it on database
    then on iOS deserialize it and continue your "Getting Started" example , using compiled rules to avoid code generation on this platform
    so, to illustrate it using your "Getting Started" example :

    On Windows
    //Load rules
    var repository = new RuleRepository();
    repository.Load(x => x.From(typeof(PreferredCustomerDiscountRule).Assembly));

    //Compile rules
    var factory = repository.Compile();
    Find a way to save compiled rules code

    and On iOS :

    //retreive compiled rules code
    var factory = new FactoryFromSomething()

    //Create a working session
    var session = factory.CreateSession();

    //Load domain model
    var customer = new Customer("John Doe") {IsPreferred = true};
    var order1 = new Order(123456, customer, 2, 25.0);
    var order2 = new Order(123457, customer, 1, 100.0);

    //Insert facts into rules engine's memory
    session.Insert(customer);
    session.Insert(order1);
    session.Insert(order2);

    //Start match/resolve/act cycle
    session.Fire();
    Hope this strange use case is clear and hope you can help us :)

    1 reply