Jump to content

Bug in JKI SM ?


Callahan

Recommended Posts

Hi all,

I think I have found a bug in the JKI State Machine.

Let me explain it in details :

 

1) "Macro: Exit"

If "Close Panel on Exit" is TRUE, ie :

-executable mode

-or Front Panel originaly closed (called by a splash screen for example)

 

Macro: Exit

 

so, the states put in "FIFO" by "Macro: Exit" state are :

UI:Front Panel State >> Close

then

Data:Cleanup

then

Exit

 

2) "UI:Front Panel State >> Close"

The first executed state "UI:Front Panel State >> Close" execute the "FP : Close" method, if the Front Panel is "Open".

HERE IS THE POINT

The "FP : Close" method put the VI out of memory if there is not at least one reference open to it.

So, code in "Data: Cleanup" state DOES NOT EXECUTE (no code has to be put in the "Exit" state).

 

3) Application 1

-Put a new blank JKI state machine on a diagram

-Shunt the "Close Panel on Exit" to TRUE

-Put break points in "Exit" state and "Data: Cleanup" state

-Run the VI

---> You see that the code stops before breakpoints, or just at the first break point put in "Data: Cleanup Up". This is due to the fact the "FP : Close" method take a certain amount of time to totally execute. IT IS A RACE CONDITION. If code in "Data: Cleanup" take a lot of tim, it would not be completly executed.

 

4) Application 2

-Put 3 sequenced dialog boxes in the "Data: Cleanup" state. Compile the code. Execute it and quit it. The 3 dialog boxes are not displayed.

 

5) Note 1

NI says : "In order for any VI to run, it must have at least one reference open to it. When you display the front panel of a VI, the front panel itself serves as an open reference to the VI".

---> In the case of the JKI state machine, the VI server reference constant "This VI" is used. For me, the reference "This VI" does not open explicitly a reference on a VI, so it's not necessary to close it as it is done in the state machine. If "This VI" was an explicitly open reference on the VI, the "Close Panel on Exit" method would not stop the execution of the VI but just hide the FP.

 

6) Note 2

The "exit labview" function is not used in the JKI State Machine. If the VI concerned is the main VI, the "exit labview" has to be used, I think, no?

 

Conclusion, to discuss

-The close reference function used in the Data:Cleanup has not be used. I'm interesting to know your point of view about the "This VI" reference. For me it is not an explicitly open reference able to maintain the vi in memory.

-The "FP: Close" and "FP: Open" methods can be used without wiring the reference inputs

-The order of the states in "Macro: Exit" has to be changed :

Data:Cleanup

Exit

UI:Front Panel State >> Close

-Maybe the "FP : Close" method has to be put out of the main while loop of the state machine, to properly stop this loop.

-In a main VI, the "exit labview" function has to be used if there is more than one main VI to ensure the total close of all VI. But in this case, if "exit labview" is used, "FP : Close" method can't be used before.

 

Please, let me know your point of view. All this topic is done after some tests, but errare humanum est.

 

Callahan

Link to comment
Share on other sites

Hi Callahan,

 

Thanks for posting your feedback on this.

 

You are correct: "This VI" reference is not an explicitly opened reference able to maintain the vi in memory. And, yes, the top-level VI use case is one where the JKI State Machine needs some minor tweaking, as you've described.

 

One other consideration is that if the VI in question is reentrant, then "Open VI Reference" will return in a new instance of the VI, rather than opening a reference to running instance of the VI (whereas "This VI" returns the reference to the actual clone instance that is running). It's possible that there's a work-around for this issue.

 

I'll try to get some of the other JKI team members to jump into this discussion -- the office is rather quiet right now, due to the holidays ;)

 

Cheers,

Link to comment
Share on other sites

Thank you very much for your answer Jim.

I have some others things to add :

There are 3 mains ways to use a state machine :

-as a Main VI

-as a subVI

-as a dynamic VI

 

For me, the CleanUp state will execute correctly only if state machine is used as a dynamic VI, because there will be a reference open to it.

I think the JKI state machine can't be used as it is, while I'm pretty sure that common users use it as it is and want use it as it is.

I think many people think their cleanup state work correctly, because they have never errors, but in fact the code is simply not executed.

Are you agree ?

Link to comment
Share on other sites

Thank you very much for your answer Jim.

I have some others things to add :

There are 3 mains ways to use a state machine :

-as a Main VI

-as a subVI

-as a dynamic VI

 

For me, the CleanUp state will execute correctly only if state machine is used as a dynamic VI, because there will be a reference open to it.

I think the JKI state machine can't be used as it is, while I'm pretty sure that common users use it as it is and want use it as it is.

I think many people think their cleanup state work correctly, because they have never errors, but in fact the code is simply not executed.

Are you agree ?

 

Hi Callahan,

 

Yes, I think that you raise an important point. Most of our team is out of the office until next week. I'll make sure that this topic gets some attention ;)

 

Thanks,

Link to comment
Share on other sites

  • 2 weeks later...

Hello Michael,

 

I think it is not the good solution :

The State Machine VI will open a reference to itself, yes, and be able to maintain itself in memory.

But if this VI is used as a subVI or as a main VI, so the CleanUp state will close this reference with CloseRef VI.

It involves that the last state Exit (the one with the stop while loop condition to true) will not execute.

Your solution works, but for me if the state Exit is implemented, the code have to pass in it, exit the while loop and finish properly all the code in the diagram.

It is just a philosophy question...It avoids to cogitate a lot to understand how the state machine will stop.

 

In all cases, my point of view is that it is necessary to update the JKI state Machine.

I do love OpenG and JKI work, but for me this is a problem which can absolutly be resolved for everybody.

 

Other point : you did not wire the error output of the OpenRef VI... ^^

 

Thanks for your time !

 

Callahan

Link to comment
Share on other sites

I think I understand your concern now. You are specifically trying to address the use-case of this VI being top-level. The main problem is the "UI: Front Panel State >> Close" state which executes before the Data Cleanup. If closing the front panel means that no other VI panels will be open then, yes, this will cause LabVIEW to leave memory and terminate all VIs.

 

Also, another concern is if this is used as a dynamic VI then code will not execute if you execute the Close VI Reference function.

 

However, since LabVIEW will exit at that point, then it's not of too much concern if we cleanup the VI reference. Is there? However there is a problem if you are performing other code in that frame such as file IO or hardware communication tasks.

 

To address the issue of not executing the Data Cleanup state after the VI panel closes then you will have to modify the sequence. You can add a state before the data cleanup and panel close state to perform any additional tasks you need. One way is to edit the Macro:Exit as shown below.

 

IMG_1_14_2010__00.png

 

Regarding the Exit LabVIEW function. This is not required because once all front panels are closed then LabVIEW will exit.

 

Also note that you should not add any code in the Exit state (as stated by the comment on the diagram). That state is only there to stop the loop.

 

Please keep in mind that we fully expect that this framework will not address 100% of the use-cases, and that it's expected that you will have to modify the sequences as you require in your application. Having said that, I can see how it may be misleading to call one state, Data: Cleanup, and people may end up putting critical code in there that may not execute all the time. perhaps we should rename that state to: Close Panel Reference, and create a different new state for the cleanup code. We will consider this idea in a future release.

Link to comment
Share on other sites

"You are specifically trying to address the use-case of this VI being top-level."

Yes and no. If this VI is used as a sub dialog box (front panel displayed), it will stop immediatly after FP:Close method and all states after UI: Front Panel State will not execute.

 

"The main problem is the "UI: Front Panel State >> Close" state which executes before the Data Cleanup."

YOU ARE TOTALY RIGHT!!!!

 

"If closing the front panel means that no other VI panels will be open then"

Not necessarily.

"yes, this will cause LabVIEW to leave memory and terminate all VIs."

Closing a front panel previously open without reference open to it will stop execution of the code.

 

"However, since LabVIEW will exit at that point, then it's not of too much concern if we cleanup the VI reference. Is there?"

This is not what I mean. My english is not really good, but I'd like you understand what I think. For me, whatever use of the state machine (MainVI, subVI, dymanic VI, with FP displayed or not, etc....), the FP: Close method can't be where it is actually. It's a nonsense to have an Exit state and not pass in. I'm really sure 80% users of JKI state machine use it as it is, and don't know there code in CleanUp is not executed and the Exit state not used in 60% of the cases.

 

"However there is a problem if you are performing other code in that frame such as file IO or hardware communication tasks."

You're right. But CleanUp is CleanUp. If I was a TestStand user and want using the JKI State Machine, I would put code like Close VISA and things like that in the CleanUp State.

 

"To address the issue of not executing the Data Cleanup state after the VI panel closes on a top-level VI then you will have to modify the sequence. You can add a state before the data cleanup and panel close state to perform any additional tasks you need. One way is to edit the Macro:Exit as shown below."

It is exactly what I have done. I modified the sequence, not by adding state, but by moving the UI: Front Panel State >> Close :

Data: Cleanup

then UI: Front Panel State >> Close

the Exit

but even if this is the Exit state which get the true stop condition, this is the UI: Front Panel State >> Close which end my VI.

 

"Regarding the Exit LabVIEW function. This is not required because once all front panels are closed then LabVIEW will exit."

ok

 

"Also note that you should not add any code in the Exit state (as stated by the comment on the diagram). That state is only there to stop the loop."

YES, I see. but the loop is removed from memory before it really stop with the true condition.

 

"Please keep in mind that we fully expect that this framework will not address 100% of the use-cases, and that it's expected that you will have to modify the sequences as you require in your application."

Yes, I understand. But I think the framework have to match closely to the widespread using of a state machine, I mean a Front Panel displayed, a non-dynamic VI, and a code which end at the Exit state.

 

"Having said that, I can see how it may be misleading to call one state, Data: Cleanup, and people may end up putting critical code in there that may not execute all the time. perhaps we should rename that state to: Close Panel Reference, and create a different new state for the cleanup code. We will consider this idea in a future release."

For me the problem is elsewhere. If I decide to close some references of a complexe application in the CleanUp state, I possibly have a memory leak, because the CleanUp state will not be executed.

 

Thanks for your time, and sorry for my insistence.

I'm nively proud to discuss whit M. Kring and M. Aivaliotis ^^

 

Callahan

Link to comment
Share on other sites

"You are specifically trying to address the use-case of this VI being top-level."

Yes and no. If this VI is used as a sub dialog box (front panel displayed), it will stop immediatly after FP:Close method and all states after UI: Front Panel State will not execute.

This is not true. I just tested this and it executes all code. Are you placing the VI on the diagram of a caller or are you using dynamic call methods? Even if the front panel is closed, it is still in memory because it is physically on the diagram of the caller. SubVIs always execute until completion regardless if front panels are open or closed.

 

Closing a front panel previously open without reference open to it will stop execution of the code.

This may be true for top-level VIs but I just experimented with several subVI calls (on-diagram and dynamic) and they all worked flawlessly. I placed a dialog box after the "Data: Cleanup" code executed and it popped up fine.

 

Can you explain how you are calling this VI. Perhaps a screen-shot of the diagram call will help.

 

"To address the issue of not executing the Data Cleanup state after the VI panel closes on a top-level VI then you will have to modify the sequence. You can add a state before the data cleanup and panel close state to perform any additional tasks you need. One way is to edit the Macro:Exit as shown below."

It is exactly what I have done. I modified the sequence, not by adding state, but by moving the UI: Front Panel State >> Close :

Data: Cleanup

then UI: Front Panel State >> Close

the Exit

but even if this is the Exit state which get the true stop condition, this is the UI: Front Panel State >> Close which end my VI.

 

Your solution is not preferred because you are closing the VI reference before you close the panel. The Close Panel function requires the VI reference to execute correctly. I'm not sure how this works. Unless you've moved the Close Vi Reference function as well.

Link to comment
Share on other sites

This is not true. I just tested this and it executes all code. Are you placing the VI on the diagram of a caller or are you using dynamic call methods? Even if the front panel is closed, it is still in memory because it is physically on the diagram of the caller. SubVIs always execute until completion regardless if front panels are open or closed.

This may be true for top-level VIs but I just experimented with several subVI calls (on-diagram and dynamic) and they all worked flawlessly. I placed a dialog box after the "Data: Cleanup" code executed and it popped up fine.

OK, You're right. The problem subsists only for top-level VIs. And it's possible to have more than one top level VI.

Hum...ok, the problem is not so big as I thought, but it exists, are you agree ?

 

Your solution is not preferred because you are closing the VI reference before you close the panel. The Close Panel function requires the VI reference to execute correctly. I'm not sure how this works. Unless you've moved the Close Vi Reference function as well.

This reference come from the constant "This VI". It is not an explicitly open reference. It's like the constant reference created from a control. It is not able to maintain VI in memory. So, it's not necessary to close it with CloseRef VI.

So, you're right too, I removed the CloseRef from the CleanUp state, and my Close Panel method run.

Link to comment
Share on other sites

  • 1 month later...

This is a great discussion.

 

My 2 cents...

 

Yes, there is a concern closing the Front Panel of a VI when it is a top level VI in an executable, as code may not run from that point on.

 

IMO this is not a bug of the JKI SM, rather a feature of LabVIEW that you need to handle regardless of the design pattern used.

 

The way I have handle this for top level VIs using the JKI SM pattern is along the following lines:

  • Add a case to the "UI: Front Panel State" to hide the front panel
  • Replace the "UI: Front Panel State >> Close" call with a "UI: Front Panel State >> Hidden" call in the "Macro:Exit" state
  • Run all my cleanup code as per normal
  • Once outside of the loop, wait for all other asynchronous process to complete
  • Once complete, if this VI is an executable then call the FP.Close method, destroy the VI Ref and run the standard "Exit if Executable" code

Additionally, on the flip side, wrt to executables, if you are launching your VI dynamically from a launcher-VI that then closes it's front panel, I poll to check when the front panel of the dynamic-VI goes into memory, then I close the launcher-VI. Otherwise your dynamic-VI will be taken out of memory if the launcher-VI finishes before the dynamic-VI shows its FP!

 

Cheers

 

JG

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

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