Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How will multi-threading affect the Easy Rules engine?

I am looking for a rule engine for my web application and I found Easy Rules. However, in the FAQ section, it states that the limitation on thread safety.

Is a Web Container considered as a multi-threaded environment? For HTTP request is probably processed by a worker thread created by the application server.

How does thread safety comes into place?

How to deal with thread safety?

If you run Easy Rules in a multi-threaded environment, you should take into account the following considerations:

Easy Rules engine holds a set of rules, it is not thread safe.
By design, rules in Easy Rules encapsulate the business object model they operate on, so they are not thread safe neither.
Do not try to make everything synchronized or locked down! 

Easy Rules engine is a very lightweight object and you can create an instance per thread, this is by far the easiest way to avoid thread safety problems

  • http://www.easyrules.org/get-involved/faq.html

  • http://www.easyrules.org/tutorials/shop-tutorial.html

Based on this example, how will multi-threading affects the rule engine?

public class AgeRule extends BasicRule {
    private static final int ADULT_AGE = 18;

    private Person person;

    public AgeRule(Person person) {
        super("AgeRule",
              "Check if person's age is > 18 and
               marks the person as adult", 1);
        this.person = person;
    }

    @Override
    public boolean evaluate() {
        return person.getAge() > ADULT_AGE;
    }

    @Override
    public void execute() {
        person.setAdult(true);
        System.out.printf("Person %s has been marked as adult",
                            person.getName());
    }

}

public class AlcoholRule extends BasicRule {

    private Person person;

    public AlcoholRule(Person person) {
        super("AlcoholRule", 
              "Children are not allowed to buy alcohol",
               2);
        this.person = person;
    }

    @Condition
    public boolean evaluate() {
        return !person.isAdult();
    }

    @Action
    public void execute(){
        System.out.printf("Shop: Sorry %s,
                you are not allowed to buy alcohol",
                 person.getName());
    }

}

public class Launcher {

    public void someMethod() {
        //create a person instance
        Person tom = new Person("Tom", 14);
        System.out.println("Tom:
                Hi! can I have some Vodka please?");

        //create a rules engine
        RulesEngine rulesEngine = aNewRulesEngine()
                .named("shop rules engine")
                .build();

        //register rules
        rulesEngine.registerRule(new AgeRule(tom));
        rulesEngine.registerRule(new AlcoholRule(tom));

        //fire rules
        rulesEngine.fireRules();
    }

}
like image 399
ilovetolearn Avatar asked Apr 09 '26 21:04

ilovetolearn


1 Answers

Yes, a web application is multithreaded. As you expect, there is a pool of threads maintained by the server. When the serversocket gets an incoming request on the port it's listening to, it delegates the request to a thread from the pool.Typically the request is executed on that thread until the response is completed.

If you try to create a single rules engine and let multiple threads access it, then either

  1. the rules engine data is corrupted as a result of being manipulated by multiple threads (because data structures not meant to be threadsafe can perform operations in multiple steps that can be interfered with by other threads as they're accessing and changing the same data), or

  2. you use locking to make sure only one thread at a time can use the rules engine, avoiding having your shared object get corrupted, but in the process creating a bottleneck. All of your requests will need to wait for the rules engine to be available and only one thread at a time can make progress.

It's much better to give each request its own copy of the rules engine, so it doesn't get corrupted and there is no need for locking. The ideal situation for threads is for each to be able to execute independently without needing to contend for shared resources.

like image 197
Nathan Hughes Avatar answered Apr 12 '26 11:04

Nathan Hughes