Now() and runScript(script, 5000) errors

So I am getting an error saying timer already cancelled quite frequently when trying to use a timer in expression language. The runScript is constant in the error while the now() function throws that error intermittently. I looked into the timer already cancelled error and from what I found it can be caused by numerous things including the timer was cancelled implicitly, the timer’s internal thread was interrupted, or it was garbage collected(source).
The garbage collection option seems reasonable, although my knowledge on how garbage collection works is limited, as the gateway I took this from and the one having the issue have different garbage collection systems due to increased memory usage on the newer one.

I also tried nesting the script inside of a system.util.invokeAsynchronous() but it didn’t change anything.

This is the one of the runScript functions that is throwing the error.

runScript("len(system.alarm.queryStatus(path=['**'],state=['ActiveAcked',]))",1000)

and this is the error given.

java.lang.Exception: Error executing expression binding on
AlarmCountR2.AlarmCountR2.activeAckedCount
	at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter.runExpression(ExpressionPropertyAdapter.java:92)
	at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter.startup(ExpressionPropertyAdapter.java:113)
	at com.inductiveautomation.factorypmi.application.binding.DefaultInteractionController.setPropertyAdapter(DefaultInteractionController.java:219)
	at com.inductiveautomation.factorypmi.designer.property.configurators.ExpressionConfigurator.bind(ExpressionConfigurator.java:246)
	at com.inductiveautomation.factorypmi.designer.property.configurators.ExpressionConfigurator.tryCommit(ExpressionConfigurator.java:192)
	at com.inductiveautomation.factorypmi.designer.property.configurators.ConfiguratorMultiplexor$EditorParent.tryCommit(ConfiguratorMultiplexor.java:398)
	at com.inductiveautomation.factorypmi.designer.property.configurators.ConfiguratorMultiplexor.tryCommit(ConfiguratorMultiplexor.java:546)
	at com.inductiveautomation.factorypmi.designer.property.configurators.DynamicOptsDialog.doOK(DynamicOptsDialog.java:95)
	at com.inductiveautomation.factorypmi.designer.property.configurators.DynamicOptsDialog$1.actionPerformed(DynamicOptsDialog.java:64)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
	at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.Component.processEvent(Unknown Source)
	at java.desktop/java.awt.Container.processEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.WaitDispatchSupport$2.run(Unknown Source)
	at java.desktop/java.awt.WaitDispatchSupport$4.run(Unknown Source)
	at java.desktop/java.awt.WaitDispatchSupport$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.desktop/java.awt.WaitDispatchSupport.enter(Unknown Source)
	at java.desktop/java.awt.Dialog.show(Unknown Source)
	at java.desktop/java.awt.Component.show(Unknown Source)
	at java.desktop/java.awt.Component.setVisible(Unknown Source)
	at java.desktop/java.awt.Window.setVisible(Unknown Source)
	at java.desktop/java.awt.Dialog.setVisible(Unknown Source)
	at com.inductiveautomation.factorypmi.designer.property.configurators.DynamicOptsDialog.showDialog(DynamicOptsDialog.java:163)
	at com.inductiveautomation.factorypmi.designer.model.VisionDesignerImpl.openBindingDialog(VisionDesignerImpl.java:1134)
	at com.inductiveautomation.factorypmi.designer.property.editors.bb.DynamicOptionsButton.actionPerformed(DynamicOptionsButton.java:37)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at com.jidesoft.plaf.basic.BasicJideButtonListener.mouseReleased(Unknown Source)
	at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
	at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
	at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.Component.processEvent(Unknown Source)
	at java.desktop/java.awt.Container.processEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/javax.swing.plaf.basic.BasicTableUI$Handler.repostEvent(Unknown Source)
	at java.desktop/javax.swing.plaf.basic.BasicTableUI$Handler.mouseReleased(Unknown Source)
	at com.jidesoft.swing.DelegateMouseInputListener.mouseReleased(Unknown Source)
	at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
	at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
	at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
	at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.Component.processEvent(Unknown Source)
	at java.desktop/java.awt.Container.processEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Timer already cancelled.
	at java.base/java.util.Timer.sched(Unknown Source)
	at java.base/java.util.Timer.schedule(Unknown Source)
	at com.inductiveautomation.ignition.common.expressions.functions.AbstractPollingFunction.startTask(AbstractPollingFunction.java:65)
	at com.inductiveautomation.ignition.common.expressions.functions.AbstractPollingFunction.setPollRate(AbstractPollingFunction.java:95)
	at com.inductiveautomation.ignition.common.expressions.functions.ScriptFunction.execute(ScriptFunction.java:58)
	at com.inductiveautomation.ignition.common.expressions.FunctionExpression.execute(FunctionExpression.java:69)
	at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter.runExpression(ExpressionPropertyAdapter.java:83)
	... 102 more

Ignition v8.1.7 (b2021060314)
Java: Azul Systems, Inc. 11.0.11

I don’t know why that error is occurring periodically, it might be worth opening a ticket with support so they can open a ticket internally if necessary…

That said, what you’re doing is a terrible idea unless your goal is to block your UI and gum up your gateway as you open more clients. Don’t abuse runScript like this, and especially don’t abuse it by querying alarms or history.

What @Kevin.Herron said, don’t do this in runScript. Make a gateway timer event that runs periodically, gets the number of alarms, and writes that to a tag, and then have your clients just read from that tag.

Generally speaking don’t use runScript with any function that has to go out and fetch something like to the db or gateway because while that’s going on the user can’t do anything. Keep it for simple calculations or lookups from a hardcoded dictionary or similar. Avoid system.db/system.alarms/system.tag calls in runScripts.

2 Likes

Ok the now functions that are throwing that error are on client tags as well but like @bkarabinchak.psi said to just have the gateway timer scripts write to tags. Thanks for your help

1 Like

A useful question to ask yourself - is there only one answer or value that should propagate down to all clients? Then it should be done once per cycle (however you define that), in the gateway context, and have your clients read from it.

Only if it is something that should vary from client to client would you want to then put it into a client timer script or in the UI logic\a script called by the UI.

1 Like

In this situation there is only one value that propagates down to all clients but that is definitely food for thought when I come across similar situations where I need to decide on whether to use client tags/script or gateway tags/script.

1 Like