From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, 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: 

Is there a way to create a more specific enqueuer for an actor?

Solved!
Go to solution

That always struck me as odd about AF. It feels you are exposing the underlying communication mechanism. Sure you've wrapped it in an enqueuer, but the name enqueuer kind if implies there is a queue. It would be nice to send a message and not really care about the delivery method.

 

DQMH hides the mechanism for requests. They are events, but the end user has no idea. For the broadcasts it does expose the events ref, so it's "half" as clean.

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 11 of 21
(1,766 Views)

@Taggart wrote:

Sure you've wrapped it in an enqueuer, but the name enqueuer kind if implies there is a queue. It would be nice to send a message and not really care about the delivery method.


It does more than imply there is a queue. It explicitly says that there is a queue specifically so that you know the FIFO behavior. It doesn't say anything about the implementation of this queue. There may or may not be a Queue data type under the hood, but the abstract data type is a queue. In fact, there isn't a singular queue under the hood, there are four, and they can be moderated by network connections... the implementation is not exposed at all and can be replaced at any time, but it must maintain the queue semantics. This is a rather important promise to make to all users of the AF and is thus part of the public signature. 

Message 12 of 21
(1,752 Views)

@JimB. wrote:

I feel like there is a layer missing. That within a given actor's lvlib, both the messages and the actor itself should be private. The public class should be a wrapper that exposes each message for that actor as a method of that class.


You're not wrong, but you're not right either. The middle layer that you speak of would be a great idea, but we cannot build it. It falls afoul of the same type calculus problem that I described in the other thread. Basically, you can create the middle layer, but if you use the middle layer, you cannot inherit from the class... your caller is then locked to that specific nested actor, not any of the children. That cuts off design goal #2 of the AF, which was reuse of the code for new actors. (Goal #1 was a design that was safe from the four bugs that plagued other designs for lifetime, deadlock, echo chamber, and reliable order of messages in multi-hop delivery.)

0 Kudos
Message 13 of 21
(1,749 Views)

@AristosQueue (NI) wrote:

@JimB. wrote:

I feel like there is a layer missing. That within a given actor's lvlib, both the messages and the actor itself should be private. The public class should be a wrapper that exposes each message for that actor as a method of that class.


You're not wrong, but you're not right either. The middle layer that you speak of would be a great idea, but we cannot build it. It falls afoul of the same type calculus problem that I described in the other thread. Basically, you can create the middle layer, but if you use the middle layer, you cannot inherit from the class... your caller is then locked to that specific nested actor, not any of the children. That cuts off design goal #2 of the AF, which was reuse of the code for new actors. (Goal #1 was a design that was safe from the four bugs that plagued other designs for lifetime, deadlock, echo chamber, and reliable order of messages in multi-hop delivery.)


 

I believe what you are describing here is the inheritance issue I outlined later in my comment, no?

 

You would be able to inherit from the middle layer, but the issue with making the actor class private would be having to reimplement a new actor in every concrete class. Yes, this is quite detrimental to reuse, and community scope is a mediocre (at best) work around.

 

I thought about it a bit more and realized that perhaps an alternative would be to keep the AF methods and wrapper methods in the same class, but place the AF methods in protected scope so external callers could not access them directly... But just a little more thought is definitely uncovering some code smells. The fact that the private data would contain elements relevant to both the wrapper methods and the actor methods and the actor would have a separate copy would make things somewhat confusing for the developer of such a class and definitely screams SRP violation.

 

Dropping the idea of making the actor private and just not using it directly in calling code doesn't really enforce proper usage, but might turn out to be the least hassle. Might also open the door to some slight variations on my original idea that are now rattling around in my head.

 

I know I already mentioned it, but the only good solution I can think of for the architecture I originally envisioned is with classes inside classes, thus allowing for protected internal classes. Of course, that requires a change to LabVIEW that I assume is probably unlikely to happen.

0 Kudos
Message 14 of 21
(1,734 Views)

Question: could you not just create a class that is the API for your actor? You might refer to it as a proxy pattern. It could hold onto the enqueuer and have a method for sending each message that just delegates to the appropriate send method? and if you have a child of that actor, just create a wrapper for that child that inherits from the wrapper for the parent.  Then instead of passing around the enqueuer, you pass around this proxy object?

 

Would that solve your problem?

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 15 of 21
(1,732 Views)

I don't actually have a problem. Just pontificating on some architectural thoughts. 😉 Actually, I apologize to the OP if I have totally derailed their topic.

 

And yes, that's basically what I've been trying to describe. Sorry if it wasn't clear. Most of the stumbling points in this mental exercise were around the initial vision of restricting usage of the underlying actor by setting it to some form of protected scope. That throws a monkey wrench into the inheritance structures possible in LabVIEW.

0 Kudos
Message 16 of 21
(1,723 Views)

@JimB. wrote:

I know I already mentioned it, but the only good solution I can think of for the architecture I originally envisioned is with classes inside classes, thus allowing for protected internal classes. Of course, that requires a change to LabVIEW that I assume is probably unlikely to happen.


You might be right, but I'm pretty certain I ruled out that solution working for some reason. Over the years, I've tried many attempts on this problem. It's something I've spent cumulative weeks stewing about, and I know I looked in that direction.

 

If that solution does work, internal classes have enough conceptual oddities around them that the work involved would be in the "large project" category, and if I'm going that far, I'd rather spend my time on native actors with a better type calculus so the interim layers aren't needed.

0 Kudos
Message 17 of 21
(1,716 Views)

I guess my question is why use inheritance? Instead of inheriting from Enqueuer, why not use composition and wrap the enqueuer?

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 18 of 21
(1,710 Views)

@Taggart wrote:

I guess my question is why use inheritance? Instead of inheriting from Enqueuer, why not use composition and wrap the enqueuer?


Why use inheritance for what? For actors? Nothing inherits from Enqueuer.

0 Kudos
Message 19 of 21
(1,706 Views)

@AristosQueue (NI) wrote:

@Taggart wrote:

I guess my question is why use inheritance? Instead of inheriting from Enqueuer, why not use composition and wrap the enqueuer?


Why use inheritance for what? For actors? Nothing inherits from Enqueuer.


I was responding to:

 

And yes, that's basically what I've been trying to describe. Sorry if it wasn't clear. Most of the stumbling points in this mental exercise were around the initial vision of restricting usage of the underlying actor by setting it to some form of protected scope. That throws a monkey wrench into the inheritance structures possible in LabVIEW.


 

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 20 of 21
(1,701 Views)