I am just curious about how openHAB is designed, so I go deeper to the source code of Core. I found a very interesting problem, and there are two components in openHAB core.
- The first is ModelRepositoryImpl, which is used to read rule or item files, e.g., demo.rules, and translates rules in the file into the corresponding model.
@Component(immediate = true) public class ModelRepositoryImpl implements ModelRepository
- The second is RuleEngineImpl, which is used to execute rules, for example, the startup rules.
@Component(immediate = true , service = { EventSubscriber. class , RuleEngine. class })
public class RuleEngineImpl implements ItemRegistryChangeListener, StateChangeListener, ModelRepositoryChangeListener, RuleEngine, EventSubscriber
Inside RuleEngineImpl, it will first execute startup rules by the following function.
private void scheduleStartupRules() {
ScheduledFuture<?> job = startupJob;
if (job != null && !job.isCancelled() && !job.isDone()) {
job.cancel(true);
}
startupJob = scheduler.schedule(() → {
runStartupRules();
}, 5, TimeUnit.SECONDS);
}
At first, I don’t understand why here we need a 5-sec delay, and I try to search for the reason. The only reason I found is that openHAB cannot guarantee that reading rule files will be executed before executing startup rules. The proof is that I insert two lines of logging codes, one before reading rule files, and another in the first line of scheduleStartupRules()
. I found the output is the following.
21:33:27.849 [main] WARN o.e.s.m.r.r.i.engine.RuleEngineImpl:134 - Started rule engine
21:33:28.208 [main] INFO o.e.s.m.c.i.ModelRepositoryImpl:125 - Loading model ‘demo.rules’
which shows that openHAB first tries to execute startup rules, then it tries to load the demo.rules (The sequence is random after several attempts are made). This is so weired: Rules must be loaded first before it is going to be executed, but the OSGi framework cannot guarantee that! And I believe that this is why we need the 5-sec delay to make sure that the rule will be loaded before the startup rule is executed. Can’t we find another way to solve this? Why doesn’t openHAB set different start levels for different components to make sure that some sequential tasks can work normally?