Jump to content

Consequences of unreliable run method


Recommended Posts

As LabVIEW programmers we are all fairly used to find ways to get around limitations in the development environment and G as a language, however at times those limitations and bugs are just so fundamental that it gets depressingthrowpc.gif. The graph axis bug that was introduced in LabVIEW 2009 was one such case: if you wanted to use graphs and upgrade to LV2009 you had to rewrite all your code so the scale markers would show up correcly, or wait for months to get the first revised version of LabVIEW (because even fundamental errors like that are not patched instantly....). The good thing about that example though was the fact that you could actually make a fix yourself. Well, now I'm depressed again, and this time the problem is much worse. There are ways to come around this one too, but man - it should not be necessary. I'm a bit surprised it has not been commented before, because it is not really anything new - but once you run into its consequences it is extremely frustrating...

The problem:

The run method (and related methods like set control value e.g.) runs in the user interface thread - and that thread is blocked if e.g. the user opens a contextual menu somewhere in your application :frusty: .

The consequences: In short, LabVIEW is unable to reliably start an asynchronous background process on demand.

- You can try to dynamically scale your software by instatiating a VI and run it with the run method (with Wait until done set to false), but if you need it to always happen within a reasonable time your application cannot have a user interface. It can not, because if it does then the run method might be stuck indefinetly if the user happens to e.g. open a contextual menu...

So when does this actually become a problem? Well, in my case its most painful impact is that all client-server interfaces I have in my applications are unreliable because they, in order to allow an undefined number of simultaneous clients, create session handlers dynamically. A client might do a transaction that takes a lot of time, and with multiple simultaneous clients even quick transactions would add up so handling the client transactions in sequence is not possible. Hence the use of dynamically created parallell running session handlers. This works fine, but if the local user of the server should happen to open a contextual menu my server(s) effectively become unavailable to any new connections. One minute my servers are there...the next they are practically off-line to all new clients because the local user happened to open a menu...and if we're really unlucky he might leave the PC in that condition and never return! An unacceptable situation, plain and simple.

So how do we get around this? Well, either we stop making software that both has to scale to outside requests, and have a user interface...or we predefine a maximum number of parallell processes and instatiate them in an idle condition at startup. Neither one of these make me proud or happysad.gif.

PS. When I first noticed this I posted two ideas to the idea exchange (here and here). They do not have any illustrations that catch people's attention, and as it turns out neither of them are very precise, so perhaps a new one should be formulated and illustrated - but it's kind of depressing too that so few people realise their impact.

Edited by Mads
  • Like 1
Link to comment

The problem:

The run method (and related methods like set control value e.g.) runs in the user interface thread - and that thread is blocked if e.g. the user opens a contextual menu somewhere in your application :frusty: .

The consequences: In short, LabVIEW is unable to reliably start an asynchronous background process on demand.

Thanks for bringing this to my attention!

I played around a bit and generated a nutshell project in LV 2010 to demonstrate this problem.

You can see cleary that the Run VI method does not start while any menu is open (this may be a context menu or a VI window's menu).

The Get/Set Control Value methods are executed correctly even while a menu is open.

I think if this is reported to NI, the first answer will be "Expected behaviour", which is of course correct.

But it doesn't change the fact that this is a very bad trap to run into. It can really render a very powerful design pattern unusable.

So, what can be done about this?

I think there are two options how NI could improve this in future versions of LV:

  1. The Run VI method could be improved so that it may be executed even while the UI thread is busy (or there might be a new method to do this).
  2. The code that handles the menu could be improved so that it does not block the UI thread all the time (it's not doing much anyway, so why does it have to block this thread?).

But even if we manage to convince NI of this, we will still have to wait a while unitl a LV version becomes available that fixes this.

So let's think about what we can use as a workaround until then.

My idea :

Put the asynchronous VI together with it's startup code (especially the Run VI invoke node) into a DLL and call this DLL in your application.

I haven't tested this yet, but I think this should work, because the DLL is running in another application instance.

Test_UILock.zip

  • Like 1
Link to comment

...I think if this is reported to NI, the first answer will be "Expected behaviour", which is of course correct.

...

I wonder if this issue can be tracked back to the OS and virtual memory.

From what I understand (other jump and fix my errors please) LV force a page fail on all of the code when it loads a VI to avoid pagefail waits while running. While the OS is handling the page faults and mapping virtual memory for the app, it is running in kernal mode (show kernal times in the task manager) to do the memory managemnt work. While in kernal none of the normal tasks are even concidered unti lthe memory mapping is correct and complete.

Loading other code (i.e. opening Excel) while LV is running has always had this affect.

SO that all makes senes to me.

THe only hole I see for LV to escape thru is "in what thread do the menus run?" and there maybe some hook keeping menus in the UI thread.

The above is a lot of speculating on my part. Take it with a grain of salt.

Ben

  • Like 1
Link to comment

I don't know the details of your application, but is it necessary to run all your code together in the same application? Sure it would be nice if LabVIEW were re-architected to make this all work, but it shouldn't be necessary. You can run a separate instance of LabVIEW (copy the EXE to LabVIEW2.exe) and run your servers there, or just build them into a separate application.

In the real world, your client/server should running as a service. We use FireDaemon to accomplish this for our client/server system which can accept an unlimited number of connections.

Services generally don't provide a user interface directly, so it's not unreasonable for NI not to have planned for this. You have a manager or client app which uses files or a database or TCP/IP on the localhost to pass events and data to the server. In general this should make your application more robust.

Edit: OK, I just read your posts over on the dark side. You already know all the stuff I wrote, and AQ told you that this is not going to change anytime soon. Why are we having this discussion?

Edited by jdunham
  • Like 1
Link to comment

Why are we having this discussion?

Because if we did not then surely nothing would happen?;)

I think there are two options how NI could improve this in future versions of LV:

  1. The Run VI method could be improved so that it may be executed even while the UI thread is busy (or there might be a new method to do this).
  2. The code that handles the menu could be improved so that it does not block the UI thread all the time (it's not doing much anyway, so why does it have to block this thread?).

But even if we manage to convince NI of this, we will still have to wait a while unitl a LV version becomes available that fixes this.

So let's think about what we can use as a workaround until then.

The two options you mention are nicely formulated. In the long run I hope NI will implement the first one, but the second one would be fine too.

As part of the first option you mentioned a third one, that's my straw of hope here:

Perhaps there is an option where another type of method is developed, one that would have limitations in other respects, but which would solve this particular problem preliminarily (until a more fundamental rewrite has become inevitable, one that also allows for an optimal solution to this issue).

Edited by Mads
  • Like 1
Link to comment

I wasn't aware of this issue. Thanks for pointing it out!

Have a round of :star: on me!

Loading other code (i.e. opening Excel) while LV is running has always had this affect.

I've noticed the unresponsiveness before but never understood why it was happening. I'm not that familiar with OS technology but I guess I'm a little surprised the OS as a whole is either in kernal mode or user mode. I would have thought that would be defined by each process.

Link to comment

Mads, thank you fro the find. I used RunVI method without realizing this.

The only other reasonable alternative to using Run method I know is http://expressionflo...04/worker-pool/ It should not suffer from switching to UI exec subsystem

But that one is more suited for running a set of identical "worker threads" that sizes with the size of task rather then launching a plugin.

Edited by mzu
Link to comment
  • 4 weeks later...

Here is a modification of silmaril's example to include the alternative to Run VI method I described earlier. In order to run it you have to download worker pool from Tomi Maila's blog: http://expressionflo...4/worker-pool/.

class Incrementer inhertis from class Command. Everyhting works asynchronously with UI as expected. Once again Kudos to Tomi Maila for contributing this solution to the community and one more reason for all of us switch to LVOOP if you have not already ...

Test_UILock_classes.zip

post-2886-0-27487800-1298609555_thumb.jp

Edited by mzu
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.