Currently I am finding that series of sequential system.tag.writeBlocking commands causes unfortunate stuttering within the vision client. I know there is system.tag.writeAsync, but I want to be 100% sure that they are being written sequentially.
To be very confident, I would want to know the answer to the following questions:
Does system.tag.writeAsync respect the order of command at all -- if I call five of these in a row in the same script, can I be sure that the tags will be written in the requested order?
Does it respect global requested order? If I have two scripts running concurrently, can I be confident that if script A calls writeAsync before script B that script A's write will go through before script B?
How can I await this write in script? There are various circumstances under which I want to wait for that write to complete before I continue, but I really don't want to block the main UI thread. Python 2.7 doesn't have asyncio so I am not confident using any of the asyncio rules that I know. I already tried a global variable tied into the async callback, but this didn't work. Do I have to set up memory tags and use them as intermediaries?
Basically, I'm not sure if this async system is all in a single thread elsewhere or if they are able to race each other. Fingers crossed they are in a single thread!
The only scenario where you are guaranteed any ordering is if you pass multiple tags/values into a single writeAsync call. You shouldn't make any ordering assumptions about any of the other scenarios you listed.
writeAsync takes a callback function. You continue doing work in the callback, and if that work involves touching Vision UI components you need to make sure to use system.util.invokeLater.
So how am I supposed to do something like the following without locking the UI? all of these tags are modbus registers on a PLC and there is latency from multiple factors:
write(reg_1, False) # shut off power
write(reg_2, 10) # set charging rate
write (reg_1, True) #reactivate power
while True:
if read(reg_3) > 98: # if fully charged
write(reg_1, false) #shut off power
write(reg_4, True) # do something interesting
break
wait(0.01)
write(reg_5, status_code)
Do I have to make a chain of callback functions and actually stuff all of my code inside of them? They can't communicate with the main thread very easily so at best this method would very annoying and difficult to organize.
Its good that I can queue a group of sequential writes in a single call, but how can I properly ensure that multiple writes are respectful of the ordering between them?
You can pop off the new thread and then disable a button or start a spinner or whatever to indicate work is being done, then at the end of that thread use invokeLater to touch the UI and indicate it's done. Or just let it happen in the background with no indication... whatever works.
What happens when you call writeBlocking inside of a function that is called using invokeAsynchronous? Is it exactly the same as calling writeAsync, functionally the same, or something else?
So far adding a foo wrapper around my script and then calling system.util.invokeAsyncronous(foo) at the bottom seems to improve the situation but still run slower than I'd expect.
It's not the same, the whole function you pass to invokeAsynchronous is running in a new thread, but each of the writeBlocking calls is going to make a round trip to the gateway as it sends the write and waits for the result. Where possible, batching your writes so that you write to multiple tags in a single writeBlocking might improve the performance a bit. But because of your ordering requirements you need to do blocking writes. If you want A to happen before B then you need to wait for A to finish before doing B.
If the client-gateway round trips are hurting the performance, you might also consider moving this logic to the gateway and triggering it from the client somehow - tag change, system.util.sendMessage or sendRequest, etc. Might be a little trickier to deal with feedback though.
Even then, because of the ordering requirements, you're still waiting on round trips to the PLC for each write.