04-29-2013 01:41 PM
David Staab wrote:
One of my challenges in AF is that even when I want to do this, I still have to make a series of messages that share the queue of the target actor with the sending actor. (See my Data Broadcasting library...the token is used to share the recipient's "address" and has to be passed around the "control tree".) So in AF, there is no code size benefit to bypassing the tree.
My primary goals when writing code relate to code maintenance, not code size. I get far more utility out of letting the code grow as much as required to keep it easy to understand and easy to change than I do by optimizing the code for speed or size. I subscribe to the "first make it work, then make it fast" school of thought. In your case, it sounds like the amount of boilerplate code requires an unacceptable amount of effort to make changes.
David Staab wrote:
Could AF benefit from adding a registry of named actor queues so anyone can send a non-control message to anyone else by name? (It could be made fancier by treating the name as an interface and allowing a message to be sent to multiple recipients registered for that interface.)
My personal belief is the community would probably benefit from an optional add-on package implementing an actor to fill the role of registry and redirect messages, but I don't think that capability should be built into the AF core library directly. It's a "great power, great responsibility" feature. Too many developers would start using it without understanding what they are doing. (QSM redux.)
I've written a few apps that had a lot of messages traversing the tree, and the amount of code that does nothing other than forward the message to the next actor in the chain can get cumbersome and interfere with understanding the system. I haven't quite gotten to the point where I've written a dedicated message dispatcher, but I've certainly thought about it.
04-29-2013 01:54 PM
David Staab wrote:
But, as I think it's been stated, only Command-type messages need the warranty of a tree. "Benign" messages don't benefit from it. If a lot of boilerplate can be removed from a big percentage of all messages in the system without considerable design risk, I'm all for it.
I haven't yet replied to that whole discussion, but the summary of my current position is that there is no such thing as "benign messages". I have been working through some of the discussion and have yet to find a case where I would agree with that analysis. Command messages and data messages do not appear to differ in any way that would lead me to agree with the difference in message passing. At the moment I don't have anything concrete to cite other than what I've already posted about the reasons behind the AF design. I am not in a good position to explore the topic further -- it would need a better test case for real world playing than I currently have. And whereas Allen was more than happy to let me jeoprodize his project for something I thought would improve it, few customers are willing to let me jeprodize their projects for something I think *won't* work. 🙂
The best I can say to this is "You might be right. Be careful."
04-29-2013 02:01 PM
Daklu wrote:
David Staab wrote:
...So in AF, there is no code size benefit to bypassing the tree.
My primary goals when writing code relate to code maintenance, not code size. I get far more utility out of letting the code grow as much as required to keep it easy to understand and easy to refactor than I do by optimizing the code for speed or size. I subscribe to the "first make it work, then make it fast" school of thought.
"Fast" and "Easy" are orthogonal vectors. AF is not easy to write, and is even less easy to maintain. That's my complaint, and it's the #1 issue I have with continuing to use it. (So far, it's been plenty fast for my use.)
04-29-2013 02:33 PM
David Staab wrote:
AF is not easy to write, and is even less easy to maintain. That's my complaint, and it's the #1 issue I have with continuing to use it.
Yeah, I got that with a second read through and added a bit more to my post to reflect that. I agree AF leans towards the stiff side. Changes can be... unpleasant. When I repeatedly have to do something unpleasant, I typically find ways to avoid having to do it at all. Enter the MessageDispatcherActor.
I will echo AQ's caution... "Be careful." While I feel confident there is a fundamental difference between control and benign messages, it's not at all clear to me how to categorize a message as one or the other. Still lots of gray there...
04-29-2013 02:42 PM
Daklu wrote:
When I repeatedly have to do something unpleasant, I typically find ways to avoid having to do it at all.
Ditto. And sadly, that's why I try to design my AF systems to rely on as few messages as possible. It's hard to make and edit messages. That seems to completely subvert the intent of using AF in the first place, which is why I want to make it easier.
Daklu wrote:
While I feel confident there is a fundamental difference between control and benign messages, it's not at all clear to me how to categorize a message as one or the other. Still lots of gray there...
Which is why I only allow "data" messages to be considered benign in my Data Broadcasting library. "Request" and "status" messages are almost never benign.
04-29-2013 07:27 PM
Perhaps the best way to categorise messages as Benign is simply: that the system does not care whether they arrive or not. Obviously that is quite a restrictive definition but at least there is no grey!
The best example I can think of are UI update messages, or at least the subset of them that are non-interdependent.
Surely any messages which have other actions depending on their arrival or ordering are not, by definition, benign?
04-30-2013 05:10 PM
[Note to Officer Staab: I know this whole tangent discussion on control/benign messages is better suited to the other thread. But this is where people are talking about it so I'm just going with the flow, you know? Please don't give me a ticket for a topic violation. ]
fabric wrote: Perhaps the best way to categorise messages as Benign is simply: that the system does not care whether they arrive or not. Obviously that is quite a restrictive definition but at least there is no grey!
The only messages the system "doesn't care whether or not they arrive" are those messages that are filtered out by the receiving actor. However, the receiver's filter (assuming it has one) changes depending on the actor's state. No messages are always filtered out. If the definition is so restrictive very few messages can qualify as benign, there's no value in making the distinction in the first place.
Strictly speaking, I do believe the set of benign messages in a system can change during execution. However, if we're utilizing a secondary messaging routing system for benign messages the messages we send on it have to *always* be benign. We can't risk sending a benign message through a central dispatcher if that message could change into a control message during transit.
fabric wrote:
The best example I can think of are UI update messages, or at least the subset of them that are non-interdependent.
UI updates are control messages in those applications where humans play a critical role in the overall system. Without feedback from the UI the human will do the wrong thing and the system will break down.
fabric wrote:
Surely any messages which have other actions depending on their arrival or ordering are not, by definition, benign?
No, although any message that does not cause an action is, by definition, benign. Except for those messages that are filtered out, all meaningful messages do something when they arrive. The difference between control and benign is determined by the importance of the action that results from the message, not whether or not an action occurs at all.
05-15-2013 03:00 PM
I see I neglected to continue with this conversation, sorry. I was in the middle of writing my first app using Actors (my own framework) that I had the chance to do in over a year and I was waiting to see if it produced any insight. Unfortunately, the main conclusion is that the apps I work on are too small to throw up any issues of message order!
But hey, here's a screenshot anyway, of the top-level "Slug Main" actor with a schematic diagram of some of the interactions between the five actors involved (actually, 11 actors are running, including a debug logger and five clones of a reusable helper actor that allows the main actors to "publish" messages):
"Slugs", BTW, are short sections of fluid in a tiny capillary that need to be created, measured, and photographed. "Slug Main" delegates most automation to a "Slug Maker" actor, which needs to create slugs through control of a "Linear Slide" actor, and also needs to receive sensor information from a DAQ actor. Note that these messages are "cross-tree" and definitely not "benign". However, the messaging setup is specified in the parent "Slug Main"; see the case shown in the bottom part of the picture where Slug Main registers the Linear Slide to receive Slug Maker's published "Requested Depth" messages (relabelled as "Set Position" to match the accepted command of the Linear Slide). To understand the cross-tree interaction, and if desired to change it to a strict tree topology, I only have to consider/change the code of Slug Main. So in a way, I'm not really breaking the tree topology, as the parent actor is still acting as an intermediary between it's subactors. I imagine a similar thing can be done in the Actor Framework using self-addressed messages created by the parent actor.
-- James