When are gateway scripts reloaded?

I’m wondering when scripts used in the gateway are reloaded after modification.

F.e. imagine I want to read a value from a tag process it, and write a result value to another tag or log it in a DB. The code to achieve this is placed in a shared script, and fired on a value changed trigger script.

When I save a new version of the script, the changes get applied automatically, and I don’t have to shut down all places where the script is used (which is great ofc). But I wonder if the script execution can stop midway between reading and writing. Or if there’s a guarantee that this thread will finish correctly, and the new script will only be used on the next trigger.

What happens when I wrote an infinite loop during the processing? Is there a timeout to halt the thread and start executing the new code anyway? How big would that timeout be, is it enough to do some network stuff?

Script restart will not interrupt scripts already running, and those already running scripts will still be in the old module global environment. If you have long-running threads, they will continue running. Infinite loops with no mechanism to exit are a huge problem.
If I have a need for such a thread, I generally have it save its own thread name in a string memory tag, and periodically check that it still matches. When a restarted script module starts a new copy, it’ll overwrite the tag and the old thread will see it. The old thread can then intelligently shut down.

Thanks, that’s very nice to hear. It means that as long as I don’t make mistakes data integrity is guaranteed. It also means that if data is corrupted, I’m the one to blame … damn …

Infinite loops are never needed inside Ignition either. There’s no need to use polling loops as the scripts can be called from gateway timer events or from other triggers (like tag changed).

So getting in an infinite loop will also always be my problem … damn again …

Hmm, apparently I bumped into something that does need either an infinite loop or some other trick.

A device I want to communicate with via TCP/IP wants to keep the socket connected (otherwise I get a huge error log about disconnecting and reconnecting).

Currently, I just keep a global variable in my script holding the connected socket, but when I update, I don’t know how to close that socket as I see no way to access my old code anymore. And as the device only allows one connection, this means I have to keep trying to connect until the garbage collector cleans up the socket (which can take a long time, but luckily the garbage collector is clever enough to close the socket).

Do you see a way to improve this?

That would be one of the reasons for a long-running thread (doing all the reading), started from the script module, that checks occassionally to see if a new version of the thread is trying to take its place. That triggers the explicit close so the new thread can open the socket.

1 Like

You could also stick the socket in the legacy globals dictionary. I think that survives script restarts. Be very careful, though. If you put a code object in there (custom class instance, whatever), it won’t be updated by script restarts.

1 Like

Thanks, using the globals dictionary is perfect for this situation.

I can now update my scripts live without anyone noticing it, and without having to worry about old code still running.