Custom "timer" Binding causing an error that breaks module import on views

First thing to note, we are running version 8.1.43

Over the last month I have had a bug making our development environment a huge headache. When working on a view in the designer, any calls to a script would break. When going to the logs, you would see the same error (although sometimes the type would be ‘list’ and not ‘dict’:

org.python.core.PyException: TypeError: unhashable type: 'dict'
at org.python.core.Py.TypeError(Py.java:234)
at org.python.core.PyDictionary.dict___hash__(PyDictionary.java:828)
at org.python.core.PyDictionary.hashCode(PyDictionary.java:810)
at java.base/java.util.concurrent.ConcurrentHashMap.get(Unknown Source)
at org.python.core.PyStringMap.__finditem__(PyStringMap.java:129)
at com.inductiveautomation.ignition.common.script.ScriptManager.lambda$clearProjectScriptModules$6(ScriptManager.java:661)
at java.base/java.lang.Iterable.forEach(Unknown Source)
at com.inductiveautomation.ignition.common.script.ScriptManager.clearProjectScriptModules(ScriptManager.java:660)
at com.inductiveautomation.perspective.gateway.PerspectiveModuleRpcImpl.lambda$designerScriptsModified$4(PerspectiveModuleRpcImpl.java:133)
at com.inductiveautomation.ignition.common.util.TimedRunnable.run(TimedRunnable.java:21)
at com.inductiveautomation.ignition.common.util.ExecutionQueue$PollAndExecute.run(ExecutionQueue.java:239)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)

Sometimes, the log would give us a view path as the source of the error, but nothing useful on what was actually causing the error.

Recently, I believe I found the source of the issue. For various reasons I have needed a “timer” object on views for instances such as a temporary response message based on user input. My solution to this was to create a custom object on a view component that looks as follows:

The ‘action’ binding is bound to now(1000), firing every second. It then runs this transform:

My logic behind my design was that when attempting to “do something after x seconds”, I had timing issues when setting the “x seconds” rate using now(x). Instead I would use an “enable” bit to control when the action that would require to timer to be completed, set the timestamp for the timer action to occur, and disable the timer once it’s action was completed.

The current code has been cleaned up a few times to try and clean up the issue, but it’s still occurring. Can anyone see a fatal flaw to this design that would cause this error? I can provide an exported project with the code above, but the issue has been difficult to reproduce consistently until it actually happens. I am very confident this is what is causing it and nothing else on the view(s) the error occurs. Thanks for any help.

Looks like your error matches the one from this thread, but I see that you have already replied there.

I’m assuming Phil’s fix didn’t work for you.

I’m a bit out of my area of expertise here, but it looks like this is caused by a race condition in the initialization of project library scripts not by anything in your perspective view.

I’m not sure if it will help, but I would double check that you aren’t importing project library scripts within other project library scripts. If I am understanding the issue correctly though, this race condition will still occur from gateway events that run after the script module reinitializes without import statements.

1 Like

Yeah, I tried to chase that, but I just kept finding my issues were popping up on views I was using this logic above. It’s been a frustrating attempt to solve because that thread matches my problems but my attempts to fix haven’t been fruitful.