Hi everyone,
I'm currently working with ignition perspective on a mobile app for my company.
i've noticed an high CPU usage while i'm working on this specific project and this happens only with the mobile app project. if i try to open any other project i have a CPU usage of 6-10% plus some spikes due to a gateway script used to store data from other projects to our database.
The threads with stack traces that show TIMED_WAITING are idle. Bindings and transforms tend to be brief workloads that are rarely captured by the "snapshot" nature of a thread dump.
Consider opening a support ticket to obtain guidance on the loggers that would be most useful at DEBUG and/or TRACE level to identify your culprits.
You can also do your own logging in transform scripts. If you suspect any particular script, adding logging would be my first step.
i suspect some circular bindings, but i'm kind of new of the platform so i'm not that skilled to find them out. could a transform on a expression binding like this be a problem?
I don't see any circularity in that sample, because it has no side effects. (Please post code using this forum's "preformatted text" style instead of screenshots.) That is, there aren't any assignments to other Perspective properties within that transform. Those are often the source of circular evaluations that the designer cannot identify automatically.
Side note: You should not use multiple separate tag read operations in your scripts. Always assemble all necessary tag paths for reads into a list, and use a single system.tag.readBlocking() to get them all at once.
If the transform runs often, it would be even better to use separate custom properties with indirect tag bindings to track those tag values, and reference just the custom property in the script.
In this sample, they can not do that, as the second read path is dependent on the result of the first.
Looking at it, I would say there is potential of using tags to store values that do not need to be globally persistent values. (e.g. designParameters).
Ah, indeed. That dataset of user-specific parameters should be indirect bound to a session or view custom dataset. With expression bindings to extract the CoreID and DeviceID into view custom properties. Then a final indirect binding on a view custom property to subscribe to the power tag.
Then this entire binding and transform becomes a simple expression binding. No script at all.
This app is designed so that each user sees only the data sent to our mqtt broker from their devices. Hence the need to divide the folder path by user name.
Also (unfortunately) I had to use nested system.tag.browse because each user can have multiple cores (one folder per core) to which multiple devices can be connected ( one folder per device). as a result I need two nested for loops using system.tag.browse to reconstruct the complete tag path.
You should be performing a three-level browse in your project startup script and caching the result in a document tag in each folder. So your UI just indirect binds to the document tag in the user folder. No other browsing.
(Perhaps add an administrator button that will re-execute the browse when necessary.)
i have more or less the same script in the gateway scripts.
it browses every 30 sec either MQTT engine and default folders and compare them in order to import to default new users' folders. i imagine that i should change that script too
A tip for your browsing algorithm: accumulate tag paths and document dictionaries in two lists that are initialized (empty) before the outer loop. Every summary tag to be written would be appended to them after any inner loop is finished.
Then a single system.tag.writeBlocking would update everything at the end.
If you wish to avoid disrupting users with tag updates when no changes are found, before writing, read all of those document tags into another list (you have the tag paths in a list at that point). Then iterate through the three lists, constructing a new pair of lists (tag paths and documents) for only the changed documents. Use system.tag.writeBlocking on just that pruned pair of lists.