Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How do you organize Interfaces and PPL?

Hi all,

 

I'm designing an AF based application where actors are built into PPL. But I'm not sure how to handle Interfaces.

 

Usually (when I develop small AF app, without PPL), I create a second lvlib containing the actor interface. In the nested actor, I use "Send Msgs" from my interface. And my caller inherits from the interface.

 

But with PPL, I'll need to first create my interface, build it into PPL and then call it in the nested actor, am I right? That's more to handle.

Why not having a top lvlib containing both the nested actor and it's interface lvlibs? I get only 1 PPL for 1 actor. The only downside I can think of is in case I want multiple actors to share the same interface. But if I don't, is it ok to do so?

0 Kudos
Message 1 of 14
(1,049 Views)

It always depends.... if you're SURE you are not reusing the interface again... yet what's the point in having an interface used just by a single actor?

 

For inspiration, I highly recommend Allens presentation at GDevConNA https://youtu.be/ngx_nh0wBGQ?feature=shared

0 Kudos
Message 2 of 14
(1,041 Views)

The goal is to be able to re-use the nested actor in other applications. If I don't use an interface, it'll have a dependency to the calling actor, preventing reusability.

 

I'll watch the presentation right now, it's on point!

0 Kudos
Message 3 of 14
(1,016 Views)

I stopped using PPLs, but agree the only downside to your proposal is not sharing interfaces for multiple actors. I don't think I've ever reused an interface in that way, but maybe you have.

 

I like to make my actors like this. It makes it easy to see what's going on, and to scope private messages.

 

  • Something Useful.lvlib
    • Actor Messages
      • <all Actor messages in here>
    • Caller Messages
      • <all Caller messages in here>
    • Actor.lvclass
    • Caller.lvclass <an interface that the Caller is expected to implement> 

I like this because it namespaces nicely (Something Useful.lvlib:Actor.lvclass), and it's much easier to rename the actor. The whole thing should package nicely into a PPL.

 

Speaking of namespaces, watch out for the Caller interface methods... probably need to prefix each VI with the interface name to avoid collisions (for example if many Callers have a "Configure" message with different I/O).

 

Good luck with the PPLs...

Message 4 of 14
(982 Views)

Me neither, Ive never reused an interface. But if the case happens I guess I'll separate it from the actor.

 

I like your architecture, it's simpler that way.

0 Kudos
Message 5 of 14
(918 Views)

@Oli_Wachno wrote:

It always depends.... if you're SURE you are not reusing the interface again... yet what's the point in having an interface used just by a single actor?


This.

 

Edit to add:  I do take your point about decoupling.  I often have interfaces *just* to decouple actors.  But I'd have them in separate PPLs.  Interfaces are foundational software elements.

0 Kudos
Message 6 of 14
(898 Views)

@OneOfTheDans wrote:

 

I like to make my actors like this. It makes it easy to see what's going on, and to scope private messages.

 

  • Something Useful.lvlib
    • Actor Messages
      • <all Actor messages in here>
    • Caller Messages
      • <all Caller messages in here>
    • Actor.lvclass
    • Caller.lvclass <an interface that the Caller is expected to implement> 

The down side to this is that your Caller *library* is coupled to Something Useful, and is therefore coupled to everything that is called in Actor.  If any of that stuff is in a library (like another of your actor libraries), you'll load all of *that* stuff.  You can build some pretty long coupling chains that way.

0 Kudos
Message 7 of 14
(886 Views)

Not sure I follow the issue with chained coupling. Do you agree it's standard practice to keep an Actor and its Actor Messages in one library (regardless the naming convention)? Then any Caller Library:Actor is already pulling in the whole Something Useful library, Actor, and dependencies. What additional coupling is added by including Caller Interface.lvclass in the same Something Useful library?

 

To your other point - do you have a practical example where multiple actors use the same interface? The closest I've come to that has always been naturally solved with inheritance, like a Base Module:Actor (with it's Caller Interface & messages) plus subclasses for My Module.lvclass. The best case I've seen for this was a fellow recently asking about 1 interface for every single message, so Actors could mix/match what they transmit and subscribe. I think this was for GUI work, in particular.

0 Kudos
Message 8 of 14
(876 Views)

I think (could be wrong) the suggestion is if you split like this:

 

Interface.lvlibp

- Interface

- Public messages for interface methods

 

Concrete.lvlibp

- AwesomeActor

- implementation of the interface

- Private messages as needed

 

then caller only requires the interface, and the app requires both but could conceivably load Concrete at runtime (if you wanted that).

 

An example of coupling more stuff here is if Concrete's AwesomeActor also calls stuff from DatabaseLogging.lvlibp, or FileWriter.lvlibp, etc (because the interface may not care about these things).


GCentral
Message 9 of 14
(870 Views)

@cbutcher wrote:

Interface.lvlibp

- Interface

- Public messages for interface methods

 

Concrete.lvlibp

- AwesomeActor

- implementation of the interface

- Private messages as needed


We might be talking about different things? I think you're describing that AwesomeActor implements the Interface, thus decoupling messages sent down the tree (caller-to-nested). What I meant to suggest is an interface for the return data sent up the tree (nested-to-caller). I'll try to redo the tree for clarity...

 

  • Main Application.lvlib
    • Actor.lvclass
      <launches Useful.lvlib:Actor.lvclass, and inherits Useful.lvlib:Caller.lvclass>
  • Useful.lvlib
    • Actor Messages
      <virtual folder of all Actor messages in here>
    • Caller Messages
      <virtual folder of all Caller messages in here>
    • Actor.lvclass
      <generates Caller Messages, which are sent to the Caller Enqueuer>
    • Caller.lvclass
      <an interface expected to be implemented by whatever launched this actor>

For dynamic loading and whatnot, Useful.lvlib would be an abstract actor, from which concrete actors inherit.

0 Kudos
Message 10 of 14
(849 Views)