Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

ArT_Actors: A Step beyond Actor Framework 3.0?

All,

I’ve been recently looking for a cool Messaging Solution for my new OO LabVIEW Framework. Actor Framework seems to be the best thing in town these days – but, out of the box, it does not provide support for some of my [dear] personal programming habits … so I made an effort to create a custom AF extension - but ended up with a somewhat different implementation of the Command Design Pattern.

Major deviations from AF3.0 include introducing the notion of Actor API (a new class hierarchy) and splitting Actor class into purely Functional Domain entity (Actor class) and purely Messaging Domain entity (Actor Component class). Please see attached ArT_Actors White Paper Draft for details.

It would be quite interesting to know how many of you consider items 1 – 6 (in the Analysis section) important for your projects and to get a crude priority rating for each (Critical| Important | Don’t Care).

I would also appreciate getting feedback on the overall design from those, who have time and patience to go through the White Paper Draft (pick 1 or 2 features you like/dislike most).

I am arriving in Austin on Sunday, heading back to Bay Area after lunch on Friday. For those going to NI Week - we can get together and discuss the subject in person.

Thanks,

Dmitry

Message 1 of 62
(20,068 Views)

Regarding item 5 and the Thermocycler Actor example: shouldn't actors endeavor to read all their mail promptly?  Having cancelable or pausable messages, or message priority even, makes sense for a job queue, but should an Actor's message queue be treated as a job queue?  The thermocycler run may take minutes or hours, but the Thermocycler Actor should be reading all its incoming messages during that time.  Some of those messages may involve adding jobs to an internal priority job queue, and some further messages may involve pausing or canceling those jobs, but this really should be handled by the actor, not the messaging system.

-- James (who, sadly, will not be at NI Week)

0 Kudos
Message 2 of 62
(3,718 Views)

There's a lot of info there that will take some time to absorb, but here are my initial comments:

1. A Caller Can Execute an Arbitrary Message on Actor's Private Data

I don't understand what you mean by this statement.  Can you provide a use case or simple example code explaining it?

2. Different Calling Modes for Messages

Meh, having various message modes built into the framework isn't important to me as long as there is a way I can implement them in the rare situations where they are needed.  Having blocking messages built into the framework may make it harder for developers unfamiliar with actor-oriented programming (aop) to adapt to the expected asynchronous nature of actors.

3. Separating Actor Functional and Message Handling Domains

I agree with you to some extent, but I think it is more a matter of how people are developing actors rather than a shortcoming of the AF itself.  There is nothing (afaik) preventing someone from developing a regular by-val class implementing some functionality and then wrapping it in a custom actor subclass.  I'll have to examine the document much more before I have an opinion on having separate Actor and Actor Component classes in the framework.

4. Batch Messages

Personally I think batch messages are entirely contrary to actor-oriented programming and cause more trouble than they're worth.  Wanting to implement a batch message in an actor is a code smell for me.  It's time to step back and take a look at the level of abstraction my actor exposes.  Chances are it is too fine-grained.

5. AF Lacks Support for Pause/Resume/Cancel, etc.

I agree AF doesn't have built-in support for those features, but they are not difficult to implement in places where it is needed.  I'm not convinced they should be made part of a framework.  (See this thread.)

6. Dependency Inversion and Dependency Injection

I fully agree with you regarding the advantages of DIDP^2 and would like to see more people use it, but at the same time everyone has their personal preference and is limited by various constraints.  In general I follow the pattern you suggest by having the class constructor method accept all the parameters the object need to function and leave everything else (such as the Launch method) separate.  Would the AF benefit by splitting this functionality into two methods?  I don't know... I haven't used the AF enough to have an opinion on that.

What out-of-the-box features your framework supports is largely determined by the audience you're targeting with it.  If you're expecting advanced developers and/or experienced aop developers to use it, many of the features you discuss might be useful.  But all of those features also adds complexity for users who are just learning oop/aop and significantly raises the learning curve.

0 Kudos
Message 3 of 62
(3,718 Views)

Daklu wrote:

1. A Caller Can Execute an Arbitrary Message on Actor's Private Data

I don't understand what you mean by this statement.  Can you provide a use case or simple example code explaining it?

Daklu,

I truly admire the speed and quality of your responses J I function at much lower frequency rates. However, Item #1 is, probably, the most important ‘of them all’ and justifies an immediate explanation:

1.       An Actor class (AF or ArT_Actors) determines which Actor class methods may be called on a Message.Do diagram by properly setting Actor method scope. Only Public methods may be called from outside of Actor class.

2.       In AF, a caller implements his own messages with custom Do method payloads. An AF Actor Message Loop will execute a Do method of any message posted to its Caller-To-Actor Queue. If Do diagram calls Actor object methods - To More Specific typecast function inside has to return a No Error (i.e. Message uses the right Actor Object type on its connector pane).

3.       However, an Actor class cannot prevent custom Message.Do method executing an arbitrary VI or LabVIEW function:

a.       Wait (60000 msec) function – blocking the Actor Message loop

b.      Delete (C:\, Entire Hierarchy=TRUE, Confirm= FALSE) function

c.       Or a more sophisticated payload of caller's choosing

This is the point where excrements may start hitting the fan (I am not referring to the Cooler AF Demo here).

4.       Example 1: an Actor, controlling a Stage, may be sent a bunch of ‘caller messages’ injecting random delays in Stage Subactor’s Message Loops – simulating a mechanical stage malfunction and making Service Engineers scratching their heads and swapping stage controllers ($5000/unit) and stage assemblies ($10,000/unit) with no success (charge for a service on-site visit may easily add another $1,000 per day).

5.       Example 2: With an intimate knowledge of customer hardware one can distort RT control loop timings, ultimately leading to a catastrophic failure without ever issuing a single command to any HW subsystem (Stuxnet comes to my mind at this point)

6.       Example 3: In a distributed AF application one may inject a bunch of ‘custom messages’ to a remote AF server – streaming out sensitive file data from a local database or HDD, without leaving a trace in application source code

7.       Example 4: A less catastrophic and more realistic one – leaving a diagnostic output in a shipping system – a developer of an unrelated subsystem added an ad hoc diagnostic dump message (without making any notes) and left on a honeymoon. Locating such ad hoc messages in large systems is no trivial task.

I think you get the picture. But it gets even worst – turns out I can easily hack (staying within G) my way into Object Private Data given:

·         Access to by-value object on a wire at run-time

·         Access to Object class source code at compile time (no need to alter the code)

Both are available to Actor caller – setting stage for a complete compromise of Actor functions (like zeroing balance of your banking account).

ArT_Actors prevent these vulnerabilities (except the hacking case) by introducing Actor APIs:

·         Target Actor Message Transport reference is hidden in Actor API private data (no way to send a message to Target Actor circumventing the Actor API object)

·         Actor API owns all ‘developer-approved’ Actor Messages and methods for sending these Messages (all source code is readily available in a single location for a peer review)

I can put it this way - an ArT_Actor_Class encapsulates Actor methods, while an ArT_Actor_API class encapsulates ArT_Actor_Component Messages.

Dmitry

0 Kudos
Message 4 of 62
(3,718 Views)

drjdpowell wrote:

Regarding item 5 and the Thermocycler Actor example: shouldn't actors endeavor to read all their mail promptly?  Having cancelable or pausable messages, or message priority even, makes sense for a job queue, but should an Actor's message queue be treated as a job queue? 

I am completely with you on using job queues to properly implement a thermocycler actor. Not a good example. But I often find myself in a fast paced environment (like R&D breadboard support) when you simply have no time to put in the right (from SW design standpoint) solution. Support for a generic Pause/Resume/Cancel seems like a reasonable tradeoff to me. Especially if you can completely avoid the performance penalty with Actors that do not use generic Pause/Resume/Cancel by configuring such Actors with a different Message Transport implementation.

Does anybody in the group have a good use case for a generic Pause/Resume/Cancel implementation ?

Dmitry

0 Kudos
Message 5 of 62
(3,718 Views)

Dmitry wrote:


6.       Example 3: In a distributed AF application one may inject a bunch of ‘custom messages’ to a remote AF server – streaming out sensitive file data from a local database or HDD, without leaving a trace in application source code

But the 'custom messages' must exist as part of the application source code on the AF server in order to be executed.  One can't actually inject new code remotely.  You'll just get an error if you send a message of a class not present on the server. 

0 Kudos
Message 6 of 62
(3,718 Views)

Dmitry wrote:

I truly admire the speed and quality of your responses...

Meh, anyone can bang out an informal forum post in a couple hours.  I'm impressed with the white papers the community has put out.  Yours and a couple from the guys at the Lowell Observatory come to mind off the top of my head.  I'm already a slow writer... formal documents take me for-EVER.

Dmitry wrote:

3.       However, an Actor class cannot prevent custom Message.Do method executing an arbitrary VI or LabVIEW function:

I understand my mistake.  I read section 1 as a feature you wish AF had, not as one you wish it didn't have.  That's what confused me.  That and the phrase "a caller can execute" implies (to me) that the arbitrary message is executing on the caller's thread, not on the actors thread.  Neat trick ( !?) if you can modify a by-val actor's private data from a different thread.

I agree the "I'll execute whatever you send me" nature of the command pattern seems like it could be a potential security hole in certain situations.  Is it worth spending a lot of time worrying about? Not for me. There are lots of ways malicious users could mess up a system. The low risk of a malicious user penetrating the software doesn't justify the high cost to security harden it for my customers.  If a malicious user has both source code and access to the system, mal-messages are probably the least of the customer's worries.

Out of curiosity, is ArT_Actors something you're considering releasing publicly or is it for internal use only?

(Edit - The paper references ArTwork, Test_Actor, and various other bits of code.  Any chance you can post them?)

0 Kudos
Message 7 of 62
(3,717 Views)

drjdpowell wrote:

Dmitry wrote:


6.       Example 3: In a distributed AF application one may inject a bunch of ‘custom messages’ to a remote AF server – streaming out sensitive file data from a local database or HDD, without leaving a trace in application source code

But the 'custom messages' must exist as part of the application source code on the AF server in order to be executed.  One can't actually inject new code remotely.  You'll just get an error if you send a message of a class not present on the server.

That is correct. When using Unflatten From String on a Descendant Class object (flattened and sent by another  Application Instance) one would get Error 1527 if the actual Descendant Class is not already in memory ... So the Target Application does need to have [at least one] Message class with some sort of vulnerability - allowing remote caller to load malicious message classes to memory before executing them (from a local drive or a shared network folder). Large applications often support plug-in architectures. Dropping [remotely] the 'bad seed' message class to a plug-in folder may do the job ...

I am not an expert on compromising computer systems . What I am trying to do here is evaluate types of security risks when using a generic distributed Actor-based framework.

I am curious if anyone knows a way to load a class/VI to a remote Application Instance via TCP/IP or Network Streams channel? Any such features on the embedded systems (i.e. LabVIEW RT) side ?

Thanks,

Dmitry

0 Kudos
Message 8 of 62
(3,717 Views)

Daklu wrote:


Out of curiosity, is ArT_Actors something you're considering releasing publicly or is it for internal use only?

(Edit - The paper references ArTwork, Test_Actor, and various other bits of code.  Any chance you can post them?)

I am a LabVIEW Consultant. I need a decent framework to use on customer projects. Right now I do not see any reason keeping it proprietary. The question is - making it available under which licensing agreement and the amount of time I can set aside to support ArT_Actors or ArTwork . Don’t have an answer right now …

As to posting examples and/or code snippets – I need some time to clean up the framework before posting anything. In particular - I need to spend more time on support & best practices for Composite ArT_Actors and crank out some form of the API Generator Tool (I do not see much value in AF3.0-style frameworks without a tool for generating Message classes …)

I agree the "I'll execute whatever you send me" nature of the command pattern seems like it could be a potential security hole in certain situations.  Is it worth spending a lot of time worrying about? Not for me. There are lots of ways malicious users could mess up a system. The low risk of a malicious user penetrating the software doesn't justify the high cost to security harden it for my customers.  If a malicious user has both source code and access to the system, mal-messages are probably the least of the customer's worries.

I really like the way you put it ("I'll execute whatever you send me" ). I suspect that a large number of people looking into using AF3.0 do not (or did not) realize this flip side of Command Design Pattern …

A major reason for introducing ArT_Actor_API class hierarchy was to give Actor developers control over precisely which messages callers may execute on ArT_ Actors.

As to malicious users (on the team or with access to application source code) – I do not worry about them too much either for the same reason. It’s more about providing developers the right tools to keep their code modular and well-organized. We all tend to cut corners when pushed against the wall (looming milestones, a high priority bug fix, etc.). Preventing ad hoc messaging is just a way to enforce well structured Actor code. I think we have strict type checking and class method access scope for the very same reason …

LVOOP class properties are limited to Private Scope. A class needs to implement an Accessor method to expose any property to caller (whether a child or a complete stranger). It seems to me that making all Messages “Private” and exposing them via ArT_Actor_API “accessor” methods is in line with this logic …
Although I sometimes do wish I had a way for making a specific class property Protected

0 Kudos
Message 9 of 62
(3,717 Views)

Putting "override actions" like Pause/Cancel/Resume into the framework seems like a make-work design that weighs on developers. I'd hate to have to override those behaviors with no-ops for every actor that I don't want to be pausable or cancellable. I'd much rather implement them myself for any actors that I want to have those behaviors, either by creating High-priority AF 3.0 messages that supercede the "job queue" with those commands, or using a State pattern in the actor's functional logic.

0 Kudos
Message 10 of 62
(3,718 Views)