You have this flagged as Perspective, so everything executes in a Gateway Scope, however, where exactly is this script "in the Gateway"? There are some weird legacy scoping issues that could possibly be getting in the way.
Why do it this way, when there are Gateway Timer or Scheduled Events that can already be set up to run on separate threads?
They both seem the same but probably some minor differences.
Edit #1:
I think it would be nice to call the timer through an invokeAsync to get a description of the thread in the gateway. Maybe I'll create two threads by doing so. Any thoughts on this?
No. The Script Hint Scope just lets you chose what types of functions it will hint you for. For instance if you set it to Client, then you wont see functions that can only run in the gateway. It's just a "Hint" to what you can use. It doesn't play any role in what scope the script is actually executed in.
Are you testing this in the Designer or in a real Session?
I think you're headed down a perilous road here. How do you plan to manage the life cycle of these threads? I see no way to halt or interrupt the timer. What happens if the gateway service needs to be rebooted? Or the project is saved restarting scripting?
You are right but I avoided it when I read this post:
Answering these questions:
There is no way to control them according to my research. If the gateway is rebooted or the scripts are restarted I will lose that execution.
I could use a Gateway Timer to check every XX time or Life Cycle Module. A Timer wouldn't execute in the exact moment and pturmel's module is new to me.
Can I ask what exactly it is you are trying to accomplish? From a business logic perspective. Seems like someone is supposed to press something and that is supposed to write to a tag X minutes later, is that all? If so I don’t see why a message handler wouldn’t suffice.
What if the person presses the button and the client immediately exits, I don’t think that would cancel the execution of the script since it all runs on the gateway but it I can’t say that for sure.
Press the button, send a message to the gateway message handler and that will write to the tag after X minutes (which could be sent in the payload as well), and then this will run whether the client stays open or not. Though I suppose this isn’t so different from your methodology.
Or you could have a memory datetime tag that you write the desired execution time to, another that sees if the current moment now() is past that time, and then have a tag change event on that looks at the expression tag and if true then executes your tag write. You may need another tag to store what value you want to write and what tag you want to write to if its privy to change. If that’s the case I’d suggest the first method. If it’s always going to be writing to the same tag though this method I think would be fine. Then no thread management is really required here.
Edit: If the exact execution time being a couple seconds off is acceptable, different idea would be to use a memory dataset tag (or a database table) that stores 1) What tag to write to 2) When it should be written to and 3) what value should be written to it. Then you could have a gateway timer script read the dataset tag or table every X seconds, determine what tags need to be written to, and it could potentially do more than one tag per cycle. After writing the tag you would delete it from the dataset. You would also be able to view the queue of upcoming tag writes, and so you could display that to clients or use that knowledge to disable your button if you already know that someone else pressed it and there’s one queued up already for instance. I would most likely go this way tbch.
Regardless of the client or session, if an action is performed on a component, it will execute a script XX time later.
It would be the same because a MessageHandler in the Gateway will suffer from the same conditions as any other script: Gateway restarts, script restarts, and any other condition that halts scripts.
That is like an expression tag that is always checking for the conditions to write a value. I think that could also do the trick. It wasn't my first approach.
It's something I'm looking at now. Maybe it's acceptable, I will discuss it with the team.
Meantime I will create all the necessary tags that I may use in any case. There is no harm in doing so. Then we can pick a solution.
BTW, does the code from the main post work for you? My case is closed but maybe someone finds their timer is not working. Maybe those timers where just being broken after a save. Are there other conditions to lookout for?