Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How to make Actors not shared clones or to "clean" the clones on start?

Hey All,

I am having issues with the Actors being a shared clone.  I need each instance to start totally fresh, without past history.  The shared clones mean that everytime I get an Actor launched I literally have NO idea what state this actor is in. 

In my AF project the Actors are UI elements.  During execution all sorts of things can be changed about appearance etc.  So I close that actor....  Then I re-launch it and I have all this "Pre" cleanup code to get the clone back to how it was when it was first launched.  It appears that that not using shared clones would fix this.. .but I can't. 

Thoughts?

Similarly I have an actor A who has a subPanel that an actor B is inserted into.  I close the main Actor, so A and B stop.

Now I re-launch A it tries to insert B and I get the error that B is already inserted into a subPanel.  Easy enough to add cleanup code to remove B from the subpanel on actor stop, but it is also completely un-intuitive and seems to me to be unnecessary.  I am done and have stopped A and B, they should go away.  When I need them again I want a "clean" A and B and not have to worry about what funky states and all are being stored by it being a shared clone.  In this case the fact that it is already inserted.

Thoughts?

Could we make the Actors templates or at least behave that way?  Or can I get some sort of Reset me to how I am saved on disk?   Reinit to defaults will not fix sizing of controls etc or that I have been put into a subpanel that is not running and I was not running.  Or is there a request de-allocate this instance?  I can see the memory implications of keeping this cache around however by having them non-resetable or known it makes it very difficult to program to and in our application of layers of UI Actors this is becoming an increasingly large problem.

Thanks

Evan

0 Kudos
Message 1 of 22
(5,657 Views)

NI does have some ongoing work to create an easy way to reset a panel, but it doesn't exist today.

Option one: Write a reset function that puts everything where you need it. This is good practice anyway for UI stuff -- it's where you would put your layout for different monitor sizes, different OS settings (like font size), for different platforms, or different user configurations.

Option two: Don't use Actor Core's panel directly. Instead, create a subVI and display it's panel. Use Open VI Reference instead of subVI call so that every call gets a brand new reference (the Open VI Ref node doesn't use the pool, by design and documentation).

Option three: You can edit your Actor Framework VIs, but it has enough performance downsides for other applications that I would not make that change to the AF generally.

Option one is your best bet... it's so commonly needed anyway for UI work that it's worth writing.

0 Kudos
Message 2 of 22
(5,337 Views)

My concern is that UI positioning is only part of the issue.  By using the shared clone I am getting old settings and values that are causing issues.  See the subPanel issue.  So I have identified a few bugs that this caused but how many other settings are out there that I have to force a reset.  I also can not find any documentation that discusses best practices or gotchas etc for shared instances, such as subpanel usage.

As far as Option One: Is this in the idea exchange that I need to up vote?  The idea that I cannot depend on the VI to start in the same state as it was saved in seems to me to break an enormous expectation we all have of VIs.  I understand the technical reasoning behind the shared clones, but that seems to point to the need for NI to provide the tools that counteract the issues it causes. 

For Option 3:  I am using the AF in a PPL so it is feasible for me to edit those, but what is the edit?  I can't use the non-shared clone with the dynamic dispatch?  Do I need to modify the Actor Framework to use templates?

Is there a technical reason for not having a "force reset to disk state" or request deallocation of this instance?  Because there is literally (as far as I can tell) no way to know the state of the instance being used I am concerned any solution I come up with is a whack-a-mole.  Debugging these issues becomes almost impossible and any and all testing becomes hard because how do I test the state of an instance that I can't control?  I figure if I can do a request deallocate or request "fresh" instance at least I am responsible for any slowdowns and memory issues, but I am back in control and in a known state.

Thanks,

0 Kudos
Message 3 of 22
(5,337 Views)

Evan wrote:

Is this in the idea exchange that I need to up vote?

No. It's in work already. No voting will change its pace. It's being built as part of the new platform announced at NIWeek 2016, but it's a few years out.

Evan wrote:

I also can not find any documentation that discusses best practices or gotchas etc for shared instances, such as subpanel usage.

I don't really understand the subpanel issue that you describe.

As for what to reset, it's whatever changed when your code ran on that VI... whatever it changed needs to be put back.

Option 3 is a bigger edit, wrapping things in non-dyndisp layers.

0 Kudos
Message 4 of 22
(5,337 Views)

The subpanel is based on a plugin UI element Actor Core.  You hit a button an instance is launched and shown:

  1. Button pressed and Actor A launches.
  2. A launches the child Actor B and A has a subpanel and inserts B.
  3. At some point they are closed so A stops, which stops the child B.
  4. Later the Button is pressed so a "new" instance of A is launched.  However, it is actually a cached version.
  5. A then launches B, and gets a cached version. 
  6. A tries to insert B and I get error 1145 the VI is already in a subpanel.
  7. So the "solution" is make sure during core stop all VIs are removed from SubPanels, but outside this cached clone issue this is never really needed.  If the child and parent are closing I have never worried abotu removing the child from a panel.

However, my expectation was that the cores and all had stopped and are gone. So when I got the cached instances with state from a previous stopped and gone instance that are inserted somewhere it raises issues and flags.

In regards to reseting, that is really an enormous effort for something that goes against what we expect.  Like I said it is a whack-a-mole.  Any change ever made to a VI then needs to be reset at init, but it is extremely hard to know every change that could be made to a VI especially in a plugin architecture.  I do not then control what another plugin may have done to each instance of a VI or control.

When you load a VI you see the front panel and state.  You then operate from that, you don't put in code to set every property of every control to make sure it is how you saved it.  Example: I open a VI and it has controls that are white and enabled with specific labels.  I do not expect to have to as a first step go through every control and reset it to white and enabled etc.  But because someone somewhere may disable the control or the color or any other settable property I have to now.  There has always been an expectation of starting from a known state, but with shared clones that is not really a valid expectation.  Correct?

I have never seen an example or a suggestion (which doesn't mean they aren't out there) that at the beginning of all VIs all settings are forced in.  If that exists are there tools to help us?  The idea of trying to set all controls and all properties (especially properties) to a known state sounds huge, especially because the one thing we can trust is how it loads from disk.  I must be missing something?  I am almost thinking a "Reinit to default" but being more than values being everything.  Some way to get the instance to a known state because without some sort of known state any solution becomes extremely complicated at best.  This may be what you are alluding to that is in a future LV, I just want to make sure if there is a project out there being worked on like that, it would have solved some of this.

Is there a technical reason to not have a reset to disk or request this instance is de-allocated?  Can I call revert on the clones to get back to a known state?

I do understand this is more a conversation for someday and that I have to deal with what we have now, which is why I am seeking tools to make this manageable.  We can then talk about true changes in future LabVIEW versions.

I do appreciate the advice and you being around for questions like this.

0 Kudos
Message 5 of 22
(5,337 Views)

> The subpanel is based on...

Ah. Now I understand. Yes, that's annoying.

> Is there a technical reason to not have a reset to disk or request this instance is de-allocated? 

No, there's no technical reason it couldn't exist. It just hasn't been a priority to implement. And, honestly, it's pretty rare for a UI to want a complete reset to disk. Usually its just individual regions but leaving other regions untouched in order to cut down on flicker and UI delay. And if it did exist, it still wouldn't help with the subpanel issue because the subpanel has to be cleared out of some other VI's panel.

> There has always been an expectation of starting from a known state, but with shared clones that

> is not really a valid expectation.  Correct?

Not correct. This is a problem with non-reentrant VIs and pre-allocated reentrant VIs also. It is a problem with any UI that gets reused, which means all of them except when you use a new call to Open VI Reference every time you launch the UI. Anytime you reenter a UI a second or later time, it either needs to be set back up OR it needs to have been reset when you left the function. Every dialog VI ever has to do this if it moves things around... take a look at the Three Button Dialog.vi or the General Error Handler.vi. There's nothing special about the shared clones setting in this case. You are correct about the rest of the work required. I realize you didn't expect to have to do that work. Nonetheless, it is required.

This may help you... it at least takes care of size and position for you. You can probably augment these VIs to store and restore other properties:

https://decibel.ni.com/content/docs/DOC-26783

> Can I call revert on the clones to get back to a known state?

Not while things are running, no. And that wouldn't work in a built application anyway, and you mentioned you're building an app out of this.

> I have never seen an example or a suggestion (which doesn't mean they aren't out there) that at

> the beginning of all VIs all settings are forced in.  If that exists are there tools to help us

I know I'm not being terribly helpful to you here. I wish I had more to offer, but this is one of those areas where you just have to code to the difficulty of your application. There's no shortcut. A comprehensive list is literally any change you can make on a panel is a change you may need to reset -- position, size, color, values, backgrounds, visibility, etc.

As far as the plug-ins... if every plug-in takes care of its own initialization, it's usually pretty straightforward to track "I did X, so I need code to undo X in my reset code." That makes it much more trackable.

There's no particular examples that I can think of on any of this other than the two VIs I mentioned above. Most of the time, such reset code is pretty simple -- just update position, size, and value. You've got an unusual case, apparently. I've seen one or two complex resets in my time working on LV, but it so rarely comes up, there's not a lot of discussion about it. It's usually just "position these controls with these sizes and maybe set some colors". Often times, the programmer has to do that anyway while the VI is running, so it just never gets talked about as if it is some sort of special requirement... it's just something UIs have to do commonly.

> In regards to reseting, that is really an enormous effort for something that goes against what we expect.

I understand it being counter to desires, but it shouldn't be counter to expectations. A panel stays in the state you left it in... it would be more frustrating for most apps if it didn't do that. And shared clones is documented to say that stateful qualities from previous calls will hang around.

Sorry

0 Kudos
Message 6 of 22
(5,337 Views)

Evan wrote:

7. So the "solution" is make sure during core stop all VIs are removed from SubPanels, but outside this cached clone issue this is never really needed.  If the child and parent are closing I have never worried abotu removing the child from a panel.

Not removing VIs from subpanels can cause terrible memory leaks. I would always make a point of cleaning up nicely - particularly if you intend to instantiate new clones at runtime.

0 Kudos
Message 7 of 22
(5,337 Views)

Re subpanels, I just call "Remove VI" before I call "Insert VI".

0 Kudos
Message 8 of 22
(5,337 Views)

Evan wrote:

In regards to reseting, that is really an enormous effort for something that goes against what we expect.  Like I said it is a whack-a-mole.  Any change ever made to a VI then needs to be reset at init, but it is extremely hard to know every change that could be made to a VI especially in a plugin architecture.  I do not then control what another plugin may have done to each instance of a VI or control.

I tend to have very little initialization/reset code in my applications.  UI's tend to be a mix of "View into a Model", and "Configuration":

With UI "state" that is a "View", the Model will immediatly update the View, making initialization code pointless.  Aso, reseting to "default" is just as much a violation of "viewing the model" as having "stale" values. 

With configuration, I have an initial message contain the configuration, which will set all the "state" of the UI.  This is done by one reused subVI, which deals in JSON configuration and an array of control references and a cluster of other state data.  Adding a new control is as easy as creating a reference to it and adding it to the array. 

0 Kudos
Message 9 of 22
(5,337 Views)

drjdpowell wrote:

Re subpanels, I just call "Remove VI" before I call "Insert VI".

That assumes that the current subpanel is the "owner" of the VI about to be inserted.  With the clones that is not really a safe assumption.  The clone could have been loaded into a different subpanel.

A1 loaded B1, then A2 loaded B2 etc.   Then we re-launch A1 again later and it tries to load B2.

So the subpanels have to remove the VIs on exit, or else the inserted VI can't be used by any other subpanel.

0 Kudos
Message 10 of 22
(5,337 Views)