LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Force Timeout on a Python Node

Lets a assume I am calling a python node instance. The VI has to wait until the python node has finished executing before continuing with other logic. What happens if the python function/code that the LabVIEW python node calls hangs (ex: cannot timeout accessing a resource or gets stuck in an infinite loop)? In an ideal world, the python node would have some timeout input. Is there a way to force stop the python node or the VI that is calling the python node without force closing LabVIEW? I gave it a try (see attached, LabVIEW 2020) with no success, and my initial assumption is it will not work because LabVIEW is calling a DLL (or some other python/Windows resource) that needs to complete before returning to the VI (see Timeout on a DLL Call for more information).

 

Here is some example python code that will never complete:

def my_func(my_num: int = 0, my_num2: int = 0):
    while True:
        pass

    print(1 + my_num + my_num2)
    return 1 + my_num + my_num2

 

 

If there is a way around this I would be interested to know, or at the very least to have. some way of knowing the python code has caused LabVIEW to hang. Thanks

0 Kudos
Message 1 of 9
(3,436 Views)

Yes, it's a dll call so there's no way out.

 

Best next thing is to start a VI dynamically to do the job. If that VI doesn't return an answer within the TO, stop waiting for it (while it keeps on running). This will become a problem when your program stops, because it won't if the dynamic VIs are still waiting on DLLs to finish.

 

Or you could pass a timeout to the Python code, but that might not be that easy. Either check the TO in a loop, or maybe Python can start a task and wait for it or terminate it.

 

Coroutines and Tasks — Python 3.10.1 documentation seems to indicate that there are options.

Message 2 of 9
(3,398 Views)

Python coroutines can be aborted. But the LabVIEW Python node doesn't support them AFAIK. So you would have to create a Python wrapper that starts the problematic routine as a coroutine and implements the timeout after which it aborts the coroutine.

 

You could even seperate that into a more generic Python library with one function launching the coroutine and returning some form of handle or cookie to it to LabVIEW and another Python function in that library that can be used to monitor and possibly abort the coroutine by passing it the handle you received earlier.

 

I'm not sure about the current state of coroutines in Python but in pre 3.0 versions it was still a bit of a moving target to use, as there were changes in the implementation and use of them between the different versions. It was definitely not something I felt comfortable to add to LabPython to support directly.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 3 of 9
(3,391 Views)

This is in line with what what I was thinking, thanks. Call and forget the VI and then offload some responsibility to whoever wrote the python function.

0 Kudos
Message 4 of 9
(3,361 Views)

@forward_079 wrote:

This is in line with what what I was thinking, thanks. Call and forget the VI and then offload some responsibility to whoever wrote the python function.


I'd say you don't need both.

 

Having Python abort the function (or making the function stop at TO) would be a better solution.

 

If a dynamic VI hangs in a DLL, closing your application becomes a problem. It only solves part of the problem.

0 Kudos
Message 5 of 9
(3,355 Views)

I was not really suggesting to Call and forget the VI containing the Python node. That can work one time but gives problems if you need to call this function again before the first has returned or you want to terminate your program. 

My proposal was to create the wrapper in Python by using Python coroutines. Then call the wrapper functions from LabVIEW.

 

The main problem is simply that Python really is a different environment and you can’t easily go from one environment to stop something in the other directly. Even if the LabVIEW Python Node would support coroutine execution, there are many things in the Python function you call that way that will still prevent LabVIEW from taking control of this coroutine such as the Python routine calling a synchronous Python function or a function located in a DLL.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 6 of 9
(3,317 Views)

My proposal was to create the wrapper in Python by using Python coroutines. Then call the wrapper functions from LabVIEW.


I have not used coroutines with python, but having looked through the python docs creating a wrapper using coroutines makes the most sense for ensuring that the python function called completes.

 

I was not really suggesting to Call and forget the VI containing the Python node. That can work one time but gives problems if you need to call this function again before the first has returned or you want to terminate your program. 


Thanks for pointing this out

0 Kudos
Message 7 of 9
(3,296 Views)

@forward_079 wrote:

I was not really suggesting to Call and forget the VI containing the Python node. That can work one time but gives problems if you need to call this function again before the first has returned or you want to terminate your program. 


Thanks for pointing this out


It would help to minimize the symptoms. It would not fix the problem.

 

At some point the problem will  (e.g. when closing the application\LabVIEW) come back to you for sure. Probably when it's most inconvenient, like when a deadline is near.

0 Kudos
Message 8 of 9
(3,282 Views)

I have a similar problem. A LabVIEW program runs some Python scripts. Some of them could take pretty long time, let's say 4 to 5 minutes. Sometimes the user wants to about the execution, i.e., stop the Python node. 

 

It looks like this is not a straightforward operation. Initially I was thinking about exchanging messages between the Python script and LabVIEW, but this seems more work compared to just killing the niPythonHost process from LabVIEW. It doesn't seem very nice, but it will work.

 

I could get the PID of the niPythonHost by calling a simple Python script right after creating the Python session reference, and if I need to abort, i.e., force the node to stop, I could kill this PID and close the reference.

 

Does anyone think that there is a problem with this approach? I am talking about Windows only. 

 

0 Kudos
Message 9 of 9
(3,105 Views)