Perspective invoke asychronous code example

It's absolutely a shame that inductive automation doesn't document the invoke asychronous function more. Even in the documentation there is only a mini example for vision while the scope also extends to perspective. In short, it's a very important function with a minimum of information... I'm looking to execute code asynchronously and return it in the DOM, on a page, and even at the simplest just a result in a label and impossible to find how efficiently... Disappointed

All Ignition jython scripts run in the gateway, not in the browser. How do you expect to deliver any results to the DOM of a page?

Fundamentally, system.util.invokeAsynchronous() is just a convenience wrapper around Java's native Thread class. That's it. Asynchronous threads have no connection to Perspective pages.

Not that you cannot use an async thread to do heavy lifting, but you will need to use a message to push any results back into Perspective scope.

Note that Perspective does not expose the DOM, nor provide any tools to use javascript in the browser. There are kludges for certain cases, but to really do it requires a third party module (see @bmusson's kit).

1 Like

I take a markdown component to inject some js scripts but it is not the topic here.

“but you will need to use a message to push any results back into Perspective scope.”

→I try to use system.perspective.sendMessage(“text”) but nothing appear in the message event listener

I start with this trivial code

def longProcess():
	val="test"
    system.perspective.sendMessage("text")
system.util.invokeAsynchronous(longProcess)

but i understant the send message into this thread cannot access to system.perspective so… how to? Regarding the documentation, the example use “event.source.parent” and “system.util.invokeLater(sendBack)” that are not part of perspective

Create local variables ahead of that def to capture session id and page id (via jython closure), and use them within the async function as parameters to .sendMessage() to explicitly target the origin session and page.

1 Like

my event handler listen on the “session”. when i click on a button i launch a script in “scripting” with the session id:

def runAction(self, event):
sessionId = session.props.id
async.longProcess(sessionId)

my script:

def longProcess(sessionId):
sess=[sessionId]
def sendBack():
val=True
system.util.sendMessage("right project name", "text", scope="session",clientSessionId=sess[0])
system.util.invokeAsynchronous(sendBack,sess)

but nothing appear (my event handler just change label text property)

def onMessageReceived(self, payload):

implement your handler here

self.props.text="hello"

Please reformat as code.

i have a button, onClick event:

def runAction(self, event):
	sessionId = session.props.id
	async.longProcess(sessionId)

on the scripting i have an async script:

def longProcess(sessionId):
	sess=[sessionId]
	def sendBack(sess):
		system.util.sendMessage(project="Supervisory_System", messageHandler="gtwyMess", scope="CG",clientSessionId=sess[0])
		system.perspective.sendMessage(messageType="text",scope="session",sessionId=sess[0])
system.util.invokeAsynchronous(sendBack,sess)

I have tried gateway message "gtwyMess":

def handleMessage(payload):
	system.perspective.sendMessage("text",scope="session")

i have a label with message handler “text”

def onMessageReceived(self, payload):
	# implement your handler here
	self.props.text="hello"

But wont work. This trivial code is juste to understand how async can send back data of course.

Change def sendBack(sess): to def sendBack():, then omit sess from invokeAsynchronous(). Spend some time learning how python closures work.

Don't bother with system.util.sendMessage(). Going through a gateway message handler doesn't help you, especially when the message handler's use of system.perspective.sendMessage() has no way to specify what Perspective session is involved. (And its scope='S' option can only deliver to session message handlers, not to component message handlers.)

Which part? What is your evidence it isn't working (e.g. are there errors in the logs)? Have you tried adding logging statements at various points to see where execution is being dropped?

This doesn't make sense.
Your action script has async.longProcess, implying you're attempting to call this project library function.

But in the project library, you're using system.util.invokeAsynchronous, but outside of any context?

Try this minimal example:

Project Library Script async

import time

def longProcess(sessionId):
	time.sleep(5) # NEVER ACTUALLY DO THIS, THIS IS ONLY A DEMONSTRATION
	callback(sessionId)

def callback(sessionId):
	system.perspective.sendMessage(messageType="text", scope="session", sessionId=sessionId)

Action Handler

def runAction(self, event):
	sessionId = session.props.id
	# NOTE: You pass a **callable reference** to the project library function
	system.util.invokeAsynchronous(async.longProcess, args=[sessionId])

I change

sessionId = session.props.id

by

sessionId = self.session.props.id

and the async function working.

Thanks for the sample code. I now can do some crazy things!!