While working with the Axeda Platform you will come across guard rails that limit sizes, recurrence, and duration of certain actions. When you run into these limitations, it may be an opportunity to re-examine the architecture of your solution and improve efficiency.
What this tutorial covers
This tutorial discusses the kinds of limits exist across the Platform, however it does not include the exact values of the limits as these may vary across instances. Skip to the last section on System Configuration to see how to determine the read-only properties of your Axeda Instance. You can also contact your Axeda Support technician to find out more about how these properties are configured.
Types of Limits discussed:
- Rule Sniper
- Domain Object Field Length Constraints
- File Store Limits
- System Configuration
Avoiding Rule Sniper Issues
There are two ways a rule can be sniped from statistics (recursive rules are done differently) – frequency count and execution time.
When a rule is killed, an email will be sent explaining the statistics behind the event. So what these numbers actually mean…
- CurrentAverageExecTime = loadExecTime / frequencyCount
This determines which rule is sniped... This is the longest running rule on average, NOT the most running per time period.
- FrequencyCount = how many times this rule ran in this period
This is for the rule in general - not this period
- TotalExecTime = total time this rule has executed for in a time
- MaxExecTime = longest time this rule has ever taken to run
- ExecCount = number of times this rule has ever run
- MaxFrequencyCount = max number of times this rule has ever run in a period
The Rule Sniper monitors all the rules as a unit. When the entire system is beyond the “load point” it chooses the heaviest hitting rule and kills it.
- Execution count
Execution count is how many time the rule has ran since it was last enabled.
- Maximum execution time
Maximum execution time is the max time a rule can run. This is controlled by the setting of the following in your DRMConfig.properties: com.axeda.drm.rules.statistics.rule-time-threshold
- Total execution time
Total execution is the time that the rule actually ran.
- Frequency count
Frequency is how many times the same expression rule runs in a set period of time. The period of time is set in DRMConfig.properties by: com.axeda.drm.rules.statistics.rule-frequency-period
- Maximum frequency count
Max frequency is the maximum times the expression can run
Recursive expression Rules could be triggered from actions such as file uploads, device registration and data item changes. A scenario may occur in which an Expression Rule initiates a Then or Else action that triggers itself, such as a Data type Expression Rule setting a data item. This scenario has led to the existence of the Rule Sniper, which disables Expression Rules that are triggered several times in quick succession. At times an Expression Rule may be sniped simply for being triggered too many times in too short a period of time, even though the rule was not recursive.
Setting a Data Item from a Data type Rule
In one scenario, one data item comes in, say Temperature, and you need to set a different data item of Climate based on the value of Temperature. Without any checking, a Data type Rule that sets a Data Item Value will trigger itself, leading to a recursive rule execution that will be shut down by the Rule Sniper. A way to do this without the rule being sniped is to check in the If expression that the data item change triggering the rule is the one we are interested in, as opposed to the data item that is changed because it was set by the Rule.
If: Temperature.changed && Temperature.value > 75 Then: SetDataItem("Climate", "Hot")
Since it was the Climate that changed as a result of the Then statement, the rule will not be triggered again.
***Update: In an ironic twist of fate, it turns out that the solution above only works for data items that are set to be stored On Change rather than Stored data items. Stored data items are updated whenever a new value is entered, even if it is the same value.
In this case, Temperature.changed would not trigger because the value would be the same, only the timestamp would be different. This would matter if you had the possibility of the same value happening twice consectively and needed the rule to trigger both times, but not on any other data item.
The correct solution is the following:
If: (!Temperature.changed || Temperature.changed) && Temperature.value > 75 Then: SetDataItem("Climate", "Hot")
Admittedly inelegant, this works because if any other data item is passed in, Temperature will not be passed in so there will be no value for Temperature.changed. If Temperature is passed in, it will trigger either one of the cases (not changed if the value is the same, changed if it isn't).
An alternate solution is to make use of the consecutive property of the Expression Rule.
"Execute action each time rule evaluates to true" corresponds to the consecutive property, which determines whether the rule will fire every time the If expression evaluates to true. If the consecutive property is true, it will fire every time. If it is false, the rule will trigger one time when the If expression evaluates to true, and then it won't be triggered again until the If expression evaluates to false, and then to true again.
With the consecutive property set to true, in our scenario above whenever the Temperature changes and is over 75, it will set Climate to Hot. With consecutive set to false, the rule will set Climate to Hot once, and then Temperature will have to fall below 75 and then rise above 75 again to trigger the rule again.
Sometimes you may need a recurring action to take place. An example would be if you don't need to evaluate a temperature in real time as it changes, but can check its status periodically. If the recurrence either requires or can tolerate a set delay, the best practice is to use a Rule Timer. A Rule Timer allows you to execute an Expression Rule on a schedule much like a cron job. In fact, the Rule Timer syntax is expressed in crontab format.
In order to use a Rule Timer, create an Expression Rule of type System Timer or Asset Timer. The Asset Timer allows you to scope the rule to a certain set of assets like other rules, while a System Timer is not scoped to assets. This makes a System Timer more appropriate for a rule that would execute a Custom Object, as opposed to one that creates an alarm directly on an asset.
Then create the Timer itself, which will allow you to set the schedule.
Navigate to Configuration > New > Rule Timer
With a Rule Timer, you can set a rule to run automatically with a preset delay and avoid the recurrence limit on the rule.
For more information on the Rule Sniper, there is a Salesforce Knowledgebase Solution article available to Axeda customers called What are the Rule Sniper and Rule Executor Monitor Features For and How Do They Work? as well as the Rules Design and Best Practices Guide.
Domain Object Field Length Constraints
Every stored object has limits on the length of its fields, such as name and value. If a script attempts to store a value for a field that exceeds the field length constraints, the value will be truncated to the maximum limit.
The maximum size of a data item value in the database is 4000 bytes.
Two additional constraints are a limit on number of lines in a custom object (typically 1000 lines) and on the size of a stored data accumulation that can be read out as a string (1MB).
The Help documentation available through the Axeda Applications Console contains information regarding field constraints (such as the Help pages on String Length Constraints at http://<<yourdomain>>.axeda.com/help/en/rule_action_data_entry_string.htm ).
Limits on File Store
Configurable quota limits exist on files that can be uploaded to the Axeda File Store via the SDK v2 FileInfoBridge. These limits will prevent creating FileUploadSessions, creating or updating FileInfos, or uploading file data if they are exceeded.
- File count: maximum number of files that can be stored on the system
- Maximum file size: the maximum size of any one file
- Total stored bytes: the total bytes for all files that may be stored on the system
The configuration of these limits can be found on your system by navigating to Administration > System Configuration as described below and searching for "file" in the Read-Only Properties.
The System Configuration link under the Administration tab is a useful reference for viewing Read-Only properties of how your instance is configured.
Check here when troubleshooting to determine any limit that may influence your app's implementation.
- An expression rule has a Data Trigger and in the Then Statement it sets a data item. Why is it getting disabled?
Answer: The rule is being recursively triggered so the Rule Sniper is disabling it.