Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

ArT_Actors: A Step beyond Actor Framework 3.0?

Dmitry: I understand how your architecture works. My point in asking the question about scope was an exploration of other options for modifying the already-released Actor Framework to achieve the same goals -- i.e., making it so that a nested actor can send only messages that are intended to come up the tree and not able to send any messages that are intended to come only down the tree. Splitting out the interface as you describe is not going to be possible to retrofit at this date without breaking existing code unless we are able to apply some sort of version mutation. I doubt our ability to come up with a mechanical way to take someone's existing application and mechanically transform it to separate the communications layer from the API interface. Thus I was exploring access scope definitions as a different way to define what messages go up vs what messages go down.

For example, it occurs to me that we could also solve this problem by splitting the Message hierarchy into two types of messages: Up-Tree Messages and Down-Tree Messages. We would have two different types of Enqueuers: one that accepts Up-Tree Messages only (for actor sending to its caller) and one that accepts Down-Tree Messages only (for actor sending to its nested actors). All the messages would end up in the same actual queue on the back end. But, of course, you still have the problem that a nested actor could define an Up-Tree Message to call any item in public scope. So, could we either use the existing scopes (public/private/protected/community) in a creative way to prevent the nested actors from creating messages to methods that are meant to only be called from above OR could we introduce a new scope into LabVIEW.exe to help define this situation better, without introducing the interface classes? The former is obviously easier as it requires G changes and the community could produce a new AF to support the separation. The latter would require changes to the LV language definition and would push such work out to 2014 at least (2013 being already well along in development and developers fully loaded).

So here's my idea:

  1. Introduce two new children of Message -- Up-Tree Message and Down-Tree Message (here after abbreviated UTM and DTM).
  2. Introduce Up-Tree Enqueuer and Down-Tree Enqueuer. Modify Launch Actor.vi to take an Up-Tree Enqueuer as input and return a Down-Tree Enqueuer as output.
  3. Make the Message Queue class able to return both types of enqueuers.
  4. Make methods on actors not be in the Public scope at all. Instead, put them in the Community scope and then create message classes to call those methods and name all of those message classes as friends so they can invoke the Community scoped methods. Each of those message classes would be either DTM or UTM.
  5. Make Stop be a DTM. Make LastAck be a UTM.
  6. This would not break any existing code except for nested actors that are sending Stop to the callers. It would be obvious to a developer what needed to be fixed, but I don't have a suggestion for any way to automate creating a custom UTM to send the Stop because we wouldn't know the actor class intended to receive the message.

Would the overall scheme satisfy your goals? If so, can you think of a way to fix step 6 to be automutatable?

0 Kudos
Message 41 of 62
(2,062 Views)

Alternatively, we just leave Stop as a public method, introduce both a UTM version and a DTM version of it and document it as a special case.

0 Kudos
Message 42 of 62
(2,062 Views)

AristosQueue wrote:

So here's my idea:...

IMHO you're both firing up rockets to go to space. While this problem of callee-controlling-unknown-caller can indeed occur in the existing AF, it's avoided by any good OO programmer who follows the dependency inversion principle. Anybody trying to use AF without a strong basis of experience in LVOOP should probably rethink their decision.

Instead of making the framework still more complicated and the learning curve still more like a sheer cliff, I recommend just documenting this possibility along with other "ways to shoot yourself in the foot" (like poor error handling overrides, failing to stop your AC.vi override, putting infinite blocking calls in a message method, etc.) in the whitepaper or another NI Community document.

Message 43 of 62
(2,062 Views)

In general, I think you and I agree, David... Leave it alone unless we find an elegant way to prevent it entirely. There's always a balance to be struck between documenting "don't do this" and building a wall so you can't do that. Dmitry's original suggestion would ramp the complexity, but the goal is right, now that I understand what he is aiming for. What I am laying out are options for creating that separation and see if any of them really shine -- basically, are any of the walls cheap enough to be cheaper than both the learning curve and the debugging headache when someone (deliberately or accidentally) "does that". 🙂

0 Kudos
Message 44 of 62
(2,062 Views)

Gotcha. I had the impression you were already writing the feature spec for 2013.

0 Kudos
Message 45 of 62
(2,062 Views)

AristosQueue wrote:

Dmitry: I understand how your architecture works. My point in asking the question about scope was an exploration of other options for modifying the already-released Actor Framework to achieve the same goals -- i.e., making it so that a nested actor can send only messages that are intended to come up the tree and not able to send any messages that are intended to come only down the tree. Splitting out the interface as you describe is not going to be possible to retrofit at this date without breaking existing code unless we are able to apply some sort of version mutation. I doubt our ability to come up with a mechanical way to take someone's existing application and mechanically transform it to separate the communications layer from the API interface. Thus I was exploring access scope definitions as a different way to define what messages go up vs what messages go down.


.....

1. Introduce two new children of Message -- Up-Tree Message and Down-Tree Message (here after abbreviated UTM and DTM).

....

6. This would not break any existing code except for nested actors that are sending Stop to the callers. It would be obvious to a developer what needed to be fixed, but I don't have a suggestion for any way to automate creating a custom UTM to send the Stop because we wouldn't know the actor class intended to receive the message.

Would the overall scheme satisfy your goals? If so, can you think of a way to fix step 6 to be automutatable?

Well, it seems that we don't have too much 'wiggle room' here... My gut feeling is that above solution adds unnecessary complexity and would confuse AF developers. What may be done instead (at this point) is to educate them:

  1. Make developers aware of DTM and UTM differences and the cost of DTM misuse by nested actors (coupling, etc.)
  2. Encourage developers to clearly mark UT Messages and corresponding actor methods (there should be just a few of them in each compound  actor)
  3. Encourage developers to verify that only UT compound actor methods are called in nested actor messages). Somebody can build a scan tool for this (say it searches for '<$ UTM $> in method description or block diagram.
  4. Promote (as a best practice) solutions that do not require using UTMs - so that any use of Actor-to-Caller Queue triggers a code review.

The latter can be done by "The Caller" registering a LastAck with nested actors (I think James favors this approach). Or not registering it at all if an application does not use it. I would use a basic Topic pub/sub (see my post #13) as Topic pub/sub scales well when you move from strict hierarchies to graph-like topologies ...

0 Kudos
Message 46 of 62
(2,062 Views)

AristosQueue wrote:

Ok. I see where you're coming from. Your objection makes sense.

Now, where were you eight months ago? 🙂

Eight months ago I was sitting on a open deck with a 180 degree Ocean / Kealakekua Bay view in Captain Cook, Big Island, Hawaii.  Snorkeling two best spots of the Big Island, kayaking in Kealakekua Bay, making Turkish coffee out of hand-picked Kona beans growing on the property, walking on brand-new lava fields and driving from sea level to Mauna Kea summit (13,700 feet) in 2.5 hours . I definitely wasn't concerned with AF or ArT_Actors during those 15 days ...

And you have to introduce an interface class for every pair of actor classes. And you have to downcast the interface object received to the particular interface being used, putting a lot more weight on the developer of the callee actor. Not saying its impossible, but it ain't helping the ease-of-comprehension of the system.

Well, in ArT_Actors most of this stuff should be handled by the API Generation Tool. And in most cases (excluding Blocking and Asynchronous Request modes) developer does not have to even create a message - it's all handled by the API code. So instead of 20 Message classes I have to deal with 20 methods within an API class. With good design practices APIs are highly reusable. Each API is generated from its Actor Class (one API method per Actor method), etc. And instead of a flat set of Message Classes I get a nice Message Class Hierarchy enforced by Actor APIs ... Sounds like a Structured Messaging concept to me . Don't know yet if it will be as good as Structured Data Flow - the proof of the pudding is in the eating, after all ...

What if we were to start annotating the Message Enqueuer class (formerly the Send Queue class)? Suppose when Actor A launches Actor B, it provided a list of class types as an input to Launch Actor.vi, and that list could be stored into the Message Enqueuer that is given to Actor B. Every time a message gets sent, its type could be checked against the list of approved types and rejected if it isn't on the list. That's a run time guard instead of the compile time guard.

Are there other approaches that give you the division you're seeking?

Now, that I have a much better understanding of AF3.0, I plan on reviewing what/how needs to be changed in ArT_Actors and/or AF4 to have ArT_Actors as a proper extension of AF4. There is a lot of value in being a part of such vibrant community and, besides that, I do not have enough time/bandwidth to create/maintain all the tools developers need to tackle actor-based applications. I will post the outcome here some time next week ...

0 Kudos
Message 47 of 62
(2,062 Views)

Dmitry wrote:

This junior guy sits in design meetings and is aware of overall design and Scanner internals. And he thinks of a cool way to implement a Shutter function - which requires sending a custom message to Scanner Actor - implements that message (based on intimate knowledge of Scanner plumbing) and everything is honky dory ...  Well, next month, another team try's reusing this Shutter Actor and runs into a problem because they use a different implementation of Scanner Actor for another line of products...

...Another example - that same junior screwed up with Shutter Actor data structures - resulting in Shutter Actor sending a Stop Message to Scanner Actor...

Do I see a good solution? Yes I do - instead of coupling Shutter Actor to Scanner Actor via Message Transport (Actor-to-Caller Queue), couple them via a Scanner API specifically designed for getting feedback from an Abstract Shutter....

My "good solution" would be to smack the junior engineer and remove his write permissions to the source control tree until he demonstrated the ability to make good coding decisions.  Easier, faster, and waaaay more satisfying. 

0 Kudos
Message 48 of 62
(2,062 Views)

Daklu wrote:

My "good solution" would be to smack the junior engineer and remove his write permissions to the source control tree until he demonstrated the ability to make good coding decisions.  Easier, faster, and waaaay more satisfying. 

Sure, it may be recommended as a best practice in a number of countries, but here, in the US, it would qualify as an aggravated assault

0 Kudos
Message 49 of 62
(2,062 Views)

Then make him buy breakfast every day until he fixes the build.

0 Kudos
Message 50 of 62
(2,062 Views)