From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

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?

drjdpowell wrote:


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. 

I guess my concern is that how do you know that you have saved and stored enough state info to properly reinitialize the UI?  You have saved what you assume is enough state info.  Then I come along and decide that all your colors are totally wrong and that I am going to change some other property for you as well.  Well if what I changed was not in your "state" you will now startup and not have the UI you expect.  You literally have NO idea what state you are starting the VI in.  That seems counter-intuitive at best.

0 Kudos
Message 11 of 22
(2,176 Views)

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

I may be reading too far into all this but....

Is the expectation of a cloned VI that the data of the VI would also be from the last time it was launched or is it safe to assume the data in that VI is new... I am thinking an actor class that got sent in?  Is that reset somewhere else and is sent in non-cloned?  I guess this also is the issue with uninitialized shift registers.

Because what I am seeing is I now have actor cores that have reset data and state but not a reset panel.  I understand that a panel may be left the way I left it, but I just can't see not having a reliable way of getting to a known state.

Is there a way to set the size of the pool?  So I can either set it to 0, or just launch the pool size and leave them alone so that any new clones I get are new?  Realizing that for this app I have chosen to take a performance hit. Basically be in control of the issue I am seeing.

AristosQueue wrote:

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.

I agree with this in a perfect world but I think we also have to program to what will really happen.  In general, I have found that trusting plugins too far is a great way to wind up in some bad areas.  So sure we have the various contracts of this is what plugins should do and what my inputs should be, but we also generally but range checks etc in our code to confirm that you have done that.  When it comes to the shared re-used panels it really appears there is not a reliable way of doing that.

I guess what I am really asking for is some way to have a reliable method of getting the VI and the panel back to a known state.  I am happy to add code to go from known to what I want... I just am concerned about trying to code from a ? to what I want.

But again, this is a conversation of this is how it works, so if you choose to use the Actor Cores as the UI, then this is a tradeoff you have.  You can not be assured that the panel is in any predictable format.

I would just love the reset me to disk or hell a compare me to disk... then I have a known state to work from.

Oh well.  I will just try to plan ahead for what people may change and when the bug reports come in I will add that to the init code as well.  I also am thinking that I will create an Actor Core UI.vit, and then when the core comes up I will just open a new instance.  Is there a down side to that?

Thanks all for the thoughts, I am always interested to get a deeper understand and see what others are doing.

0 Kudos
Message 12 of 22
(2,176 Views)

Evan wrote:


Then I come along and decide that all your colors are totally wrong and that I am going to change some other property for you as well.  Well if what I changed was not in your "state" you will now startup and not have the UI you expect.  You literally have NO idea what state you are starting the VI in.  That seems counter-intuitive at best.

Ah, you must be sharing references to controls, then?  You're well outside the "Actor Model", which is a motivation behind the Actor Framework.  One can only change things in an Actor by asking it to change in a message.  An actor might pass control references to a subActor, as it knows and controls the subActor, but it never passes unprotected access to some unknown party.  I actually break that rule by having a "Front Panel Manager" actor, which holds subpanel and VI references (which might be why I haven't had the subpanel problem you have had, since only one actor controls subpanels).   But the Front Panel Manager strictly does not change anything in the VIs themselves.

0 Kudos
Message 13 of 22
(2,176 Views)

Evan wrote:


I guess what I am really asking for is some way to have a reliable method of getting the VI and the panel back to a known state.  I am happy to add code to go from known to what I want... I just am concerned about trying to code from a ? to what I want.

AQ's Option (2) in his first post does what you want.  Use option 0x80 to "Open VI Ref" to get a new fresh clone. 

0 Kudos
Message 14 of 22
(2,176 Views)

Necroposting this thread because I think I found another way the reused clones break, and that's with the First Call? primitive. I am creating a UI that launches child actors that go into subpanels. Users can add or remove these as-needed (I have 8 subpanels they can use, which should be enough for 99.999% of the users of this app, since I can't dynamically add subpanels).

 

The problem is that I used "First Call?" on part of the UI code to decide when to do some initialization. Now, I can certainly work around this, but it basically makes it impossible to use First Call? since there's no way to reset it. Other GUI stuff can be reset, but AFAIK this one can't. I have to say, I may just be dense, but I don't think I've ever been able to get First Call? to work the way I want it to consistently 😁

0 Kudos
Message 15 of 22
(1,377 Views)

Off topic, but - Couldn't you achieve infinite number of subpanels with some sort of nesting/composite pattern? Top level has 2 subpanels. Then in each subpanel you load another actor that has 2 subpanels, etc. Weibe did presentation on something like this at GDevCon 1 I believe. I also believe Ethan gave a presentation at one of the CLA Summits about doing something similar with their MVA Framework. May not be worth taking the time to implement if you already something that works for you, but maybe worth considering.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 16 of 22
(1,368 Views)

You could make an "Actor Changed" inline VI that returns true the first time called in a newly launched Actor?  

0 Kudos
Message 17 of 22
(1,351 Views)

Whenever Actor Core starts running, that is first call for that actor. You should not need any First Call checks there because it is always the first call for that actor when the VI starts running. If you need First Call behavior in subroutines, pass that Boolean into the subroutines.

 

First Call only works in *any* app -- actors are not special -- when a given VI is uniquely called.

0 Kudos
Message 18 of 22
(1,336 Views)

@AristosQueue (NI) wrote:

Whenever Actor Core starts running, that is first call for that actor.

 


That's how I fixed it (just passed it in from one level up).

 


@AristosQueue (NI) wrote:

You should not need any First Call checks there because it is always the first call for that actor when the VI starts running. If you need First Call behavior in subroutines, pass that Boolean into the subroutines.

 

First Call only works in *any* app -- actors are not special -- when a given VI is uniquely called.


So basically, you cannot use First Call in the AF since clones may share data spaces. If I'm hearing you right, you MUST manually initialize anything that would otherwise use a First Call. Is that correct? Basically, First Call can't be used in AF to return True for every Actor launch event since the top-level VI (Actor Core) is Shared Clone. I suppose you could use it if a given subVI was non-reentrant and only needed to run its First Call stuff once, regardless of the number of actors that were launched.

 

It does track with my own experimenting. I did a minimum viable demonstration to convince myself that's whats going on. It's attached if anyone else wants to play around with it. Run Launcher.vi and click "Start new" and "Close last" a few times to see how First Call responds. It does make sense that it works like this, but it did bite me a bit.

0 Kudos
Message 19 of 22
(1,330 Views)

> If I'm hearing you right, you MUST manually initialize anything that

> would otherwise use a First Call. Is that correct?

 

I do not think you're understanding. Maybe you did, but your question implies that you've got to maintain your own actor state for initialization. You don't have to do that.

 

I'm saying that at the start of Actor Core *everything* is already "first call" for that actor. There's no need to check any Bool at all. If you test First Call or any other similar Bool anywhere in your Actor Core, you've already made a mistake.

 

If you want to fire an event for every actor launch, put that event fire unconditionally into Actor Core. Every time it executes is, indeed, a brand new actor. In other words, the correct way to write your code is like this:

AristosQueue_0-1592834152689.png

And that subVI? As long as it is only called during initialization of the actors, you can write it like this:

AristosQueue_1-1592834198978.png

But if you call that subVI in lots of places other than init, then you write it with an input for first call and call it like this:

AristosQueue_2-1592834262934.png

 

 

0 Kudos
Message 20 of 22
(1,304 Views)