Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Create Message from VI with parameter of type of owning actor class?

dear actors,

 

in the helper loop of an actor some time consuming tasks are running. The outcome of these tasks has influence to the private data of the actor. The plan was to keep a copy of the actor (with shift registers) in the helper loop which is updated by this long running tasks and send it back by message to the real actor, which is then updating its own private data.Therefore the plan was to use a messge with a parameter of the same type as the actor itself.

 

It looks like the Create Message script has problems to create such a message from a corresponding vi. The script creates a mess in Do.vi of the message class with the actor input and parameter input. Because the are of the same typ?

 

If I correct the scripted Do.vi manually, the message can be used and it seems working as expected.

 

Is this a known issue (LV2022Q3) or exist a fundamental reason why the framework script does not support that feature?

Is there a way to avoid that situation?

 

 

Thanks for your help.

 

 

 

0 Kudos
Message 1 of 7
(1,188 Views)

Good morning,

 

An actor process has exactly 2 parent classes. The actor class itself and the message class.

 

You would not want to write an actor class to a message as this would be an additional instance of that class, not the class itself. Meaning that this instance would have its own memory space separate from the actual actor.

 

Why not use the helper loop to keep track of the data as you said in a shift register and then when it needs to update the "Actor A", send a message to "Actor A" to update its data.

 

What I would do in this situation, instead of a helper loop keeping a copy of memory in shift registers, is to have Actor A launch a nested "Actor A*".

 

Let "Actor A*" handle the long running process and maintain the data and then either A* could send the data when it was ready, or A could request the data from A*. 

 

I think I understood your setup correctly, correct me if I am wrong. 

 

Steven Howell
Controls and Instrumentation Engineer
Jacobs Technologies
NASA Johnson Space Center
0 Kudos
Message 2 of 7
(1,174 Views)

thx Steven for your fast response,

 

according your clear words, I've got the impression that you exactly understood what I like to do. Also hope you have seen the originally attached screenshots.

 

I don't like to launch an other nested actor because the time consuming tasks are strongly coupled with this "Actor A", they are the main function of this actor and should be part of this actor and not somewhere else. To be responsive even the time consumption they have been placed in the helper loop.   

 

I do exactly what you propose:


 

Why not use the helper loop to keep track of the data as you said in a shift register and then when it needs to update the "Actor A", send a message to "Actor A" to update its data.


I send a message from the helper loop to the actor itself:

Screenshot 2024-06-26 144148.png

The data going with the message is the "helper-loop actor". The original plan was to use the private data of the actor but I had the impression that all the bundle and unbundle is quite a pain.... and this way it is also like OO in text based languages....


The UpdateActor function finally called by the message process the received data dependent on its own (real) private data.... completly actor concept style

 

Greetings Andre

0 Kudos
Message 3 of 7
(1,154 Views)

So,

 

1)  While I understand what you're trying to do (and do it myself, in different contexts), I don't think it's what you want to do here.  The actor may have other data that is *not* updating in the helper loop - like internal state data - that you would not want to replace.  The helper loop should only have the data it manages directly, and it should only send that data back to the actor for processing.  If all of that data is in a cluster, you can write it back to the actor's private data with a Bundle By Name function with a single node.  Heck, just make an accessor at that point, and call it with a message.  It doesn't get any easier than that.

 

For what you are trying to do, are you using Substitute Actor.vi when you replace the actor?  If not, you will end up dropping your self and caller enqueuers, and what you are trying to do won't work at all.

 

2)  As for your specific question, I don't recall that I ever tested for that case when I wrote this code.  I doubt it even occurred to me to send an instance of an actor to another instance of the same actor.  We *did* test for the use case of two error input clusters - one is the actual error input, and the other is just data - and that works just fine.  Do the two actor inputs have the same name, or just the same data type?

 

In any event, this is a sufficiently corner use case that I don't see it changing in the near future.  Fortunately, the workaround is pretty simple.

0 Kudos
Message 4 of 7
(1,146 Views)

dear Allen

 

thanks for your fast response...

 

1) I do understand and agree your first point from actor concept point of view.

 

2) The data has only the same type but not the same name.

 

Screenshot 2024-06-27 105307.png

 

 

You do it this way?

Screenshot 2024-06-27 112522.png

 

 

 

0 Kudos
Message 5 of 7
(1,123 Views)

@LVrooky wrote:

 

2) The data has only the same type but not the same name.

 


OK.  It's been a long time since I looked at that part of the code, so I can't say what would have to change.  It probably should be fixed, but I can't say when that will happen.

 

You do it this way?

Screenshot 2024-06-27 112522.png

 

 

 


No.  Don't carry the actor at all.  Just carry whatever data you want to transmit in a cluster, and then send that entire cluster as the message payload.  You shouldn't have to unbundle/rebundle here.

0 Kudos
Message 6 of 7
(1,115 Views)

I'll add in the warning present here. You've got duplicated state in 2 places. Keeping this in sync and handling merges of state correctly can be an absolutely arduous task as the code continues to be maintained. Maybe you write it perfectly the first time and never have to touch it again. congratulations you've reached wizard status and I envy you but that's nearly never the case. The message loop with the class private data should be the only source of truth for the actor's state. Any secondary loops should be their own self-standing entities that share data via other mechanisms with the actor data but have their own completely separate state.

 

90% of the time this can be solved by having a separate nested actor that does the long-running action while the caller actor remains responsive to the rest of the system. This provides the benefit of forcing the kind of relationship and data ownership that should be in place in this kind of parallel operation. It'll force you to think about the data/behavior relationships and enforce the messaging paradigm that is in fact present between the helper loop and the actor messaging but can get kind of blurried with other mechanisms when it's an actor core helper loop instead of a caller/nested actor relationship. This long-running actor is acceptable (even though common best guidance is to avoid long-running actions in any actor messages) because it's intended to only be used by the specific caller actor and it's all written knowing that some actions take a while.

~ G stands for Fun ~
Helping pave the path to long-term living and thriving in space.
0 Kudos
Message 7 of 7
(1,102 Views)