I am having a hard time trying to generalize a solution. I have reports that get submitted 15 minutes after production ends (it can end at variable times), as well as certain gateway functions that should happen x minutes after y condition occurs. Ideally, I'd just have a function that says "Do this as soon as it's past this date" in order to prevent a reliance on sleeping async threads, but I'm kind of at a lost for how to code this in a performant way that isn't messy.
My first idea was to just programmatically spin up a new tag that contains a dateAfter expression that executes the function in some tag change script of something, but that seems really heavy for what I'm trying to do. It would however give me visibility, in that I could make a project that looks for these types of UDTs/tags and manage them graphically.
Kinda just want to hear ideas on this, since I've been away from Ignition for 7 months and am slowly remembering some of its quirks
In general, I would use a database table to hold tasks with status, and a scheduled event to check the queue (once a minute, perhaps) for things to do. The database table would have task metadata for task type (perhaps as a function name), due timestamp, started timestamp (null while queued), finished timestamp, and optional parameters.
You will want to consider how to handle failures--which will show in the DB as entries with a started timestamp but no finished timestamp.
Yeah, I had that thought after typing out the question. I was kind of wanting a little more visibility, maybe something I could eventually spin into a module that looks not dissimilar to the running tasks page on the gateway website. However, I do think this ends up being the most practical solution.
I do worry about scope a bit, as I would think to have it both callable from a gateway context and a project context, I'd have to put all the functions in the gateway scope. Or I could have it set up as messages on a project, maybe, so that people don't feel the need to modify the gateway scripting project.
I definitely think I'll put a bit more thought and prototyping into this on my personal dev environment before bringing it up as a possible solution. I appreciate the push in the right direction, as always, though.
We’ve been working on something internally specifically for this type of thing.
It allows you to build composable workflows/steps that can be triggered now or in the future, and has a robust task retry/replay/clone mechanism that plays nice with redundancy.
It’s basically just this under the hood + a nice API.
Not sure if this is best but I'd approach it like this:
.Running -> Tag change script when it transitions from running to stopped write True to .reportPending and timestamp now+15min to .reportDueAt.
Then you have a tag driven flag and time to execute. Then use a scheduled task to monitor the tags periodically, when .reportPending is true and .reportDueAt reaches current time then execute your report and clear the tags after.
That shouldn't be too performance heavy, it also makes it easy to add a UI button that just writes True and a Timestamp for manual report colletion.