I have a rule that is generating the following error in the log. I have checks around any item to see if it might be NULL and do not see any problems despite logging every step in the rule. Any thoughts on how to debug?
From my limited testing, it seems the same rule can be running at the same time if there are 2 events that trigger it? Especially using Member of rules. That would imply more than one thread?
Global Valās can be used with near impunity since you canāt change them. Global vars are not thread safe. Local vars will only exist in the installer if the Rule running so from that perspective they are thread safe in so far as each thread gets itās own variable.
Be carful work locks. It is really easy to run into troubke with locks since it is possible for errors to occur that prevent finally from being called and your lock never unlocked.
Only Valās are available to a forEach loop. If you want to create it summarize some data from all the members of the collection you should use a map reduce.
Hard to provide useful concrete help when answering general questions without code and items to look at.
What about triggeringItem in a rule? If you are using the āmember ofā Group trigger and 2 members of that group change at nearly the same time what happens to the triggeringItem in the rule? Does each running version of the rule reference the correct triggeringItem or if the rule fires again does the triggeringItem change the one running in the rule that fired first if that rule is still running?
triggeringItem gets populated only for one ruleās context. So one instance of the rule will run with triggeringItem set to one of the items and another instance with triggeringItem set to the other item.
Iāve not looked in the code to verify this is the case but that is what Iāve observed.
Can the code below be optimized? In short, I have an item that is a member of several groups and I want to get one of these groups for further use. The group I want is a member of another group and that is how I identify the group I wantā¦
var GroupItem area = null
triggeringItem.getGroupNames.forEach [ i | // iterate over groups the triggering item is a member of
val b = gArea.members.findFirst [ a | a.name == i ] as GroupItem // find if the group is a member of gArea
if (b !== null) {
area = b // set area when we find the right group
}
]
Is no longer present in the logger after shortening the above code to a single line. All the other code in the rule is the same. Makes me think that something in the rules DSL is not thread safe?
For the optimizations, often Iāve found the best optimization is a whole other approach (e.g. not using two sets of Groups at all) but itās impossible to tell without more context.
Itās frustrating when users ask how to do something to solve a particular problem they have the way they have decided it needs to be solved without giving us the opportunity to explore other approaches that may sidestep the root cause of the problem in the first place.
null errors like that usually have something to do with type but itās hard to say if that itās there case here.
I can say this is one of the few case where the full collection of set operators would be useful because all you are doing here is taking the intersection of the two Sets.
I can say that the first approach wonāt work because you canāt access or assign a var from within a forEach loop. Though Iām pretty sure that you would get asyntax error for that. Did you watch the logs when the .rules file was loaded?
Iām not at a computer so canāt test this out, but I think using something like this would work as well:
val GroupItem area = gArea.members.reduce[ result, area | result = if(triggeringItem.getGroupNames.contains(area.name)) area else result ]
Another error I have seen with this rule in the logger is
2018-09-24 10:58:01.751 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'React on OccupancyState changed': The name 'logInfo' cannot be resolved to an item or type; line 14, column 5, length 106
This seems to only happen on the first time the rule is executed. Otherwise the logging command works.
That is definitely the known startup timing bug. The Rules start executing before everything is ready. There are all sorts of work arounds that people apply like setting a timer and only moving the .rules files over to the rules folder after enough time has passed for everything else to be loaded and the like.
I try to avoid relying too much on System started Rules until this bug gets fixed.