From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, 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 Documents

cancel
Showing results for 
Search instead for 
Did you mean: 

Beginner Tutorial (Very Simple 3-Actor System)

Attached is a step-by-step tutorial for beginners in Actor Framework. It's certainly not meant to be a base for writing complex programs; the aim is more to get some idea of the concepts involved by creating very simple actors and associated messaging. The coding style is my own and may not be to everyones taste, but it may make the program easier to understand, especially from a beginner viewpoint.

The program is written in LV2014, and I wouldn't know where to start in porting it to earlier versions (AF in LV2014 is somewhat different compared to previous versions, and personally I haven't used AF before this version). Also, even though the tutorial seems quite large (139 pages!), this is due to the fact that I tend to go into great detail in this style of tutorial. If you're used to AF, you could probably build this project in < 20 minutes. Also note that I don't use scripting tools (e.g. Actor framework Message Maker) in this tutorial as I believe it's better for beginners to be able to understand the basic principles in creating messages manually.

Actor Diagram (192x192).png

________________________________________

Draft B Update:

Added improved Stop functionality, + minor edits and typo fixes to the original.

Issue 1.0

Major overhaul following feedback from AristosQueue in this post.

Comments
JoeySpinella
NI Employee (retired)
on

Hi DMurray, thanks for posting this thorough example! I think I might co-opt it for an actor framework talk I am giving... today.

I also appreciate the thorough documentation.

I somehow got it into a state where I couldn't stop the root actor without closing LabVIEW, but it was because I wasn't paying attention to using the Launcher and it's Stop button. After trying to use it "normally", I see it works correctly.

Joey S.
Senior Product Manager, Software
National Instruments
DMurrayIRL
Member
Member
on

No problem, feel free to use it. Glad you find it useful! Regarding the Stop functionality, it is indeed quite crude. When I get a chance I will add an appendix detailing a better way to do the shut-down, but I just don't have the time at the moment.

AristosQueue (NI)
NI Employee (retired)
on

I have added this as Featured Content to the front page of the AF forum.

CaseyLamers1
Active Participant Active Participant
Active Participant
on

I have an addition that I would like you to consider.

This is in response to the class diagram on page 7. I take issue with your reply messages.

In order to make Addition and Multiplication actors reusable I would implement "Zero Coupled" messages. This makes those more modular and can be reused by creating new child messages for each new actor that uses an instance of the Multiply or Addition actor. I believe this concept is so fundamental it should be taught from the start.

Zero Coupled Messages for Addition and Multiplication.png

I have this in a PDF and could add to the document if you like. I can edit the document but I thought I would ask first.

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

AristosQueue (NI)
NI Employee (retired)
on

Casey: I am not sure if the "zero coupling" concept belongs in a getting started document. If it does belong, I would only put it in one of the two actors. One of the actors needs to be as simple as possible for an intro, and zero coupling is anything but simple if you're still trying to get your head around actors in the first place.

DMurrayIRL: I have looked at the document. Like Casey, I would like to suggest some changes, but I felt it was good enough as it stands to warrant the promotion on the front page. It'll be next week before I have time to look at it in more detail.

CaseyLamers1
Active Participant Active Participant
Active Participant
on

I feel strongly that zero coupling is such a fundamental concept that it needs to be taught from the start.

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

AristosQueue (NI)
NI Employee (retired)
on

Taught, yes. But not on the first actor definitely, and maybe not day one. This is a day one document. Zero coupling is only needed if you're really divorcing a caller and a nested actor, and that's a fairly rare use case for most users. Saying that you should use the zero coupling exclusively or even the majority of the time is just wrong. It creates needless execution overhead. We should teach the pattern and teach when to use it, yes, but not right out of the box. If you try to teach it right out of the box, you only confuse people further and you will drive them away from the AF very very quickly.

justACS
Active Participant Active Participant
Active Participant
on

AristosQueue wrote:


                       

Taught, yes. But not on the first actor definitely, and maybe not day one.

It's covered on Day 2 of the 3-day course, as part of the larger design exercise.  My limited instructional data shows that works OK.  I'll have (much) more data on this by NIWeek.

AristosQueue wrote:


                       

Zero coupling is only needed if you're really divorcing a caller and a nested actor, and that's a fairly rare use case for most users.

That has not been my experience, either with the customers I've trained, or in my own work.  All three coupling patterns are crucial.

AristosQueue wrote:


                       

Saying that you should use the zero coupling exclusively or even the majority of the time is just wrong.

I agree with this.  But in any AF project of any size, there will likely be at least one use case for it.

CaseyLamers1
Active Participant Active Participant
Active Participant
on

OK, day 2 or 3...

I will conceed that this doesn't "need" to be in this document. I just think it should be mentioned and that it should not be an afterthought.

My main motivation is that of re-use. If you are sophisticated enough to think you should use AF I suspect that you would appreciate that you can develop modules that can be used in multiple locations within an application and across multiple applications.

Modular code design is a best practice.

Is this really a rare use case? That surprises me.

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

AristosQueue (NI)
NI Employee (retired)
on

niACS wrote:

But in any AF project of any size, there will likely be at least one use case for it.


                   

Interesting. I've seen more fixed-personality systems. I've definitely seen zero coupling actors in the wild, but they aren't the majority. They're found in the majority of the big systems, but the small (fewer than 5 total actors) don't generally need them.

AristosQueue (NI)
NI Employee (retired)
on

CaseyLamers1 wrote:

If you are sophisticated enough to think you should use AF I suspect that you would appreciate that you can develop modules that can be used in multiple locations within an application and across multiple applications.


                   

Ah... no. The set of "people writing apps that need the AF" and "people using LabVIEW for the first time" are overlapping sets! The work I put into the three-actor template is specifically the people who have been asked to write a "while that happens, do this and be able to trigger this other thing and be able to abort the whole thing on a moment's notice." And they code themselves into a corner with regular LV programming. Those folks won't even be creating an actor, much less abstracting one. They just need a clean messaging system. That's all they need, and that's all I would burden them with.

When I said that I created the AF for new users, I was serious. I really had multiple people whose code ended up in my email inbox begging for help. They needed a framework that they could plug their code into with as little understanding of the surrounding environment as possible. It's part of the reason that I grit my teeth when people talk about the steep learning curve of the AF. Those are all people who keep demanding to understand the AF. Understanding is not required to use the AF successfully -- and I've seen multiple examples over the years. The Angry NI Eagles demo at the NIWeek keynote a few years ago was a pair of newbie marketing interns who used the AF without even consulting with me to build that program in a few weeks. No zero coupling patterns there!

justACS
Active Participant Active Participant
Active Participant
on

AristosQueue wrote:


                       

Interesting. I've seen more fixed-personality systems. I've definitely seen zero coupling actors in the wild, but they aren't the majority. They're found in the majority of the big systems, but the small (fewer than 5 total actors) don't generally need them.


                   

A three or four actor system is likely of limited scope, with not much internal reuse, so yeah, I can see that.

My big project from '13 only had three or four actor *classes* and used zero coupling, but there was a LOT more going on within those actors, and some of those actors were instantiated multiple times.

CaseyLamers1
Active Participant Active Participant
Active Participant
on

I get it.

Maybe all you ever do is build small tighly coupled "fixed personality" apps.

Most will continue through the arc of learning how to code more sophisticated applications and I think Zero Coupling comes into the picture pretty early on. I know I needed to use Zero Coupling as soon as I started. I have adopted it for everything that is a nested actor that needs to send a message to its caller.

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

justACS
Active Participant Active Participant
Active Participant
on

AristosQueue wrote:


                       

When I said that I created the AF for new users, I was serious. I really had multiple people whose code ended up in my email inbox begging for help. They needed a framework that they could plug their code into with as little understanding of the surrounding environment as possible. It's part of the reason that I grit my teeth when people talk about the steep learning curve of the AF.

I don't grit my teeth.  I rail against the ignorant and intentional spreading of FUD (fear, uncertainty, and doubt).

But then no on who has worked with me has ever accused my of holding back my opinions. 

justACS
Active Participant Active Participant
Active Participant
on

CaseyLamers1 wrote:


                       

I know I needed to use Zero Coupling as soon as I started. I have adopted it for everything that is a nested actor that needs to send a message to its caller.


                   

That might be excessive.  But my experience working with you is why the project provider supports abstract messages.

DMurrayIRL
Member
Member
on

Guys- thanks for all the feedback. It's much appreciated especially as I'm only coding in AF for a couple of months, so I'm a bit wary that the techniques I'm using might be incorrect (and would be a hindrance to new users rather than a help). Anything that is clearly wrong, please let me know and I'll change it as soon as I get time.

I've noticed a few issues in the document even as it stands regarding typos etc, so I'll change those first.

Regarding the discussion on zero-coupled actors, I've already started another project using the same 3-actor system, but with zero-coupled actors this time. This would allow users to compare the two techniques. I may need the code reviewed before I post it though, to ensure I have the principles correct. Should I just post it up, or can I PM it to one of you guys?

Brainstorms
Member
Member
on

niACS wrote:

I rail against the ignorant and intentional spreading of FUD (fear, uncertainty, and doubt).


                   

You are referring there, no doubt, to software project managers and end-users... 

CaseyLamers1
Active Participant Active Participant
Active Participant
on

I would be willing to review it. Nice work on this one too!

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

DMurrayIRL
Member
Member
on

Also just adding my 2cents as a new user regarding tightly-coupled/zero-coupled actors. I currently have about 10 (skeleton) actor libraries created and they all make use of zero-coupled messages in some way (for replies, obviously). But I found that when I started coding the top-level test application, which uses these libraries, I had other "project-specific" actors where tightly-coupled messages made more sense.

That said, I think I will end up coding some of these "project-specific" actors as fully-reusable actors at some point. But coding them as tightly-coupled actors as a first instance makes it easier to see how to make them re-usable as well.

DMurrayIRL
Member
Member
on

Thank you! It will be a few days at least before I have time to finish it.

AristosQueue (NI)
NI Employee (retired)
on

DMurrayIRL wrote:

Should I just post it up, or can I PM it to one of you guys?


                   

Just post it here. The whole community can take a look at it... as happened today. 🙂

dsavir
Active Participant
Active Participant
on

Hi,

I used loosely coupled messages mostly; zero coupled messages are indeed not a day 1 feature. But I agree with niACS - All three coupling patterns are crucial.

Danielle

"Wisdom comes from experience. Experience is often a result of lack of wisdom.”
― Terry Pratchett
dsavir
Active Participant
Active Participant
on

I finished reading the revised tutorial, kudos! very detailed and well explained.

Thank you!

"Wisdom comes from experience. Experience is often a result of lack of wisdom.”
― Terry Pratchett
FabiolaDelaCueva
Active Participant Active Participant
Active Participant
on

________

AristosQueue wrote:

                 

 

When I said that I created the AF for new users, I was serious. I really had multiple people whose code ended up in my email inbox begging for help. They needed a framework that they could plug their code into with as little understanding of the surrounding environment as possible. It's part of the reason that I grit my teeth when people talk about the steep learning curve of the AF. Those are all people who keep demanding to understand the AF. Understanding is not required to use the AF successfully -- and I've seen multiple examples over the years. The Angry NI Eagles demo at the NIWeek keynote a few years ago was a pair of newbie marketing interns who used the AF without even consulting with me to build that program in a few weeks. No zero coupling patterns there!

niACS wrote:

I don't grit my teeth.  I rail against the ignorant and intentional spreading of FUD (fear, uncertainty, and doubt).

But then no on who has worked with me has ever accused my of holding back my opinions. 

First of all let me commend DMurrayIRL for posting this tutorial, we need documents like this that help advance the understanding of not only important frameworks like AF but of LabVIEW in general. The LabVIEW community is a better place because of you and I apologize in advance for threadjacking …

I was debating about posting in this thread. I know that I don’t need to attend every discussion I am invited to attend, specially if the invitation doesn’t have my name on it.

I felt that this was addressed partly at Delacor, because we presented at both CLA Summits a graph showing learning curve vs complexity of different design patterns and frameworks. I felt the need to post because I have a great admiration for both Stephen Loftus-Mercer and Allen Smith, not to mention that I consider them my friends. It pains me that Delacor might be contributing to more dentist visits due to all that teeth grinding

We did not intend to present Actor Framework as complex and difficult to learn. The graph was contrasting the State Machine on one end, and Actor Framework at the other extreme, with everything else in between. We created this graph based on conversations with our customers and students we encounter when Chris and I teach National Instruments Customer Education courses. It is a very subjective graph, but there are two main points:

  1. Complexity:
    1. The State Machine only has: a while loop, a case structure, a shift register and an enumerator or a string.
    2. Actor Framework has hundreds of VIs and requires understanding of LVOOP.
  2. Learning Curve:
    1. At the very minimum, understanding of State Machine requires at least 3 days of LabVIEW Core 1 course.
    2. At the very minimum, understanding how to use AF in an application requires 3 days of LabVIEW Core 1 course and 2 days of LabVIEW Object Oriented programming course.

I agree with Allen Smith when he replied in this same forum to the question “Should I use AF?” (https://decibel.ni.com/content/message/101232#101232) with the following:

niACS wrote:

...

However, whether AF would be a good fit here will ultimately depend on a number of nontechnical considerations.

First, what is your timeline?  If you need to bang this out before the end of Q2, then trying to learn a new framework might be a challenge.  This is especially true if you are not comfortable with LVOOP, as you would have to learn that as well.  If you are comfortable with OO and can give this your full attention, though, you could get this done in that time.

Who will take over maintenance of this system when you are done?  If the project is for your own use, do what works.  But if this is for a customer who will expect to maintain their own code, then *their* experience and interest are going to matter at least as much as yours.  If they can't/won't wrap their heads around your code base because it uses OO and AF, you will have a problem.

...

Are you planning on coming to NIWeek?  I'm actually offering a free 2.5 day AF course the week before (watch for the formal announcement in this forum very soon).  If you can wait that long to take the class, you will be much better positioned to take on AF projects.”

I am looking forward to taking that class, I hope it helps me help our customers when they have to maintain an application that someone else wrote using AF and might not even be a finished application. As I have told Stephen in person, partly my vision of the AF might be tainted because I just don’t know how to teach it properly. This tutorial should help me in that regard as well.

So, if we leave everything else out, Actor Framework is indeed more complex than a simple state machine and the learning curve is longer and steeper for AF than it is for a State Machine.

In practice, one would not use a Simple state machine to solve a problem of the type that Stephen describes as:   "while that happens, do this and be able to trigger this other thing and be able to abort the whole thing on a moment's notice."

Probably using Actor Framework to write an application that needs to acquire 2 seconds worth of data from a single channel, analyze it and present it would be overkill.

The applications that Actor Framework fits are not simple applications and they don’t require a simple design pattern. They require a framework that can launch multiple asynchronous processes that communicate between themselves,  has sufficient error handling implemented and that can stop elegantly at a moments notice.

The same way one doesn’t use a hammer to build a house, one uses an automatic nail gun and a nail gun is more complex and it takes longer to learn than it does to use a hammer.  Someone who has never used a nail gun before can pick it up and shoot some nails, but the results may not always be pretty

Hope I did a better job describing here where we come from than we did in our presentation.

Regards,

Fab

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
justACS
Active Participant Active Participant
Active Participant
on

FabiolaDelaCueva wrote:


                       

I felt that this was addressed partly at Delacor, because we presented at both CLA Summits a graph showing learning curve vs complexity of different design patterns and frameworks.

I'm sorry you feel that way.  My comment was not directed at you or at anyone at Delacor.  You are prepared to have a reasonable discussion about the merits of various frameworks and their place in the larger ecology, and you bring valuable insight about what your customers are thinking and saying.  You do not spread FUD.

FabiolaDelaCueva wrote:


                       

So, if we leave everything else out, Actor Framework is indeed more complex than a simple state machine and the learning curve is longer and steeper for AF than it is for a State Machine.

In practice, one would not use a Simple state machine to solve a problem of the type that Stephen describes as:   "while that happens, do this and be able to trigger this other thing and be able to abort the whole thing on a moment's notice."

...

The applications that Actor Framework fits are not simple applications and they don’t require a simple design pattern.


                   

Yes to all of this.

People like to say "you need an architect to use Actor Framework."  This is true, but reverses causality.  Systems that are sufficiently complex to require an architect would likely benefit from the Actor Framework.

Put another way,

FabiolaDelaCueva wrote:


  1. Learning Curve:
    1. At the very minimum, understanding of State Machine requires at least 3 days of LabVIEW Core 1 course.
    2. At the very minimum, understanding how to use AF in an application requires 3 days of LabVIEW Core 1 course and 2 days of LabVIEW Object Oriented programming course.

The moment you attempt to build a system with multiple state machines, this comparison changes to:

State machines:  Core 1 (3 days) + Time learning how other people pass messages between their state machines.

Hopefully, whoever you study uses standard techniques.  Hopefully, they've covered issues like race conditions, error handling and successful shutdown.

In the wild, I suspect this last portion is learned as needed over weeks or months, and incompletely.

The up front cost for getting into AF is certainly steeper.  People see that up front cost and conclude that AF is therefore just harder.  They don't see the cost involved in oher approaches because they pay (or have paid) that cost over time.

FabiolaDelaCueva wrote:


                       

I am looking forward to taking that class,

I'm looking forward to having you and Chris there.

davidpcl
Member
Member
on

I've been reading this thread with interest as I've now used Actor on a number of projects so feel I can probably speak with a certain amount of confidence on this subject.

Actor is indeed simple, but what I personally found is that it took me a full project lifecycle and a certain amount of trial and error to appreciate that and have that eureka moment with it - there's alot more plates to spin up in your head (conceptually) than say firing up a few daemons with queues between them.

An example of this is that out of the box (in 2013), if an Actor throws an error then the whole application just dies so an intial reaction is 'well that's not very good'!. A bit of digging and you then realise that the Handle Error.vi's default behaviour is to do this, and by overriding it and putting something in there to catch and do something with that and not output a stop then you've gone from having something really flakey to with a single stroke making your application have bullet proof error handling with very little effort.

In terms of the zero coupling debate. I would have to say that I am personally in the camp of saying that this to me is a fundametal aspect of Actor that significantly weakens it's brilliance as a framework without having it - and I say this out of experience as I had a horrendous episode last year with a very large application that effectively seized up at edit time due to a top level Actor having visibility of a large number of child Actors (which also had visibility of the top level Actor) which meant that even if you loaded one of the child Actors it pulled in the top level and all the other Children as dependencies.

This also caused problems as we were using some single seat licences for toolkits which meant that a totally un-related child Actor wouldn't compile.

The other issue related to this which made me uncomfortable is that there were 2 or 3 of us at any one time working on this, and it made each child Actor inherently less testable and more difficult to sandbox, and having these inter-Actor dependencies (making up hyphenated words here!) in the context of all the software I have developed in my life using various languages just felt wrong.

The problems were fixed by using abstract messages, but I have to say that it did make me seriously question my use of Actor going forward, and the one Actor project I've done since this has used abstract messages from day one and certainly any I do in the future will do this as well.

The other big benefit of abstract messages (as has been mentioned) is the re-use aspect. One of the killer features for me of using Actor and a key reason why I will continue to use and love it is that a couple of years ago I developed a mult client TCP/IP Actor. By making the interface to this Actor abstract I have been able to re-use this a number of times now which means that by being pedantic about handling say all UI activity in messages I can add a scripting interface on to any Actor Framework I create in hours rather than days and without in any way modifying or compromising the integrity of any part of the software other than to add a remote message handler method (defined to the TCP/IP Actor at runtime) for it to push on to to the Frameworks core on receipt of a message.

David Clark
CLA | CTA
IDEX Biometrics UK Ltd
Hampshire, England
Rafal_Kor
Member
Member
on

when creating Do.vi overrides, why is the "To more specific class" function needed twice. It seems that one of the instances of it does not do anything with its specific class refernce output?

p.s. the answer maybe obvious, but i'm actually using your tutorial to learn this framework, as i'm the first time user of it.

AristosQueue (NI)
NI Employee (retired)
on

Radical_Raf: There should be a block diagram comment explaining it (we create the comment as part of the template). Short answer: this is a trick I worked out to make the memory management of LabVIEW way more efficient for transmission. It is not a solution that I like, but it works to make messsage handling generally high speed. I need better language elements to improve it further and eliminate the duplication.

Rafal_Kor
Member
Member
on

Not to be obnoxious with silly beginner question, but why isn't the launcher considered an actor. what if i need to pass messages/data to it, assuming that my main application's GUI is to reside in the actor core.vi of the root actor? For example, how can something as simple as moving the application stop button to the actor core, be done without making the launcher just another actor?

AristosQueue (NI)
NI Employee (retired)
on

Notice that all of that "Stop" business is in a disabled frame of a structure. It's all commented out. I suggest DMurrayIRL remove it entirely.

(Bold Face used to indicate changes I would like to see made... the rest of the text is explanatory.)

This is one of those things I was hoping to comment on at some point to suggest as a change to this document.

The launcher should be bare bones to just get things started and then go away. In general, if my entire app is actors top-to-bottom, I prefer my top-level VI be nothing more than this:

Untitled.png

That can get annoying during development, so I would consider having a diagram disable structure that I can enable when I'm ready to build.

Note that the Boolean to open the panel is NOT wired in my bit of code. I only use that during debugging because it doesn't work in the run time engine, so I don't publish examples that use it. Instead, I prefer to modify the Root Actor's Actor Core in the VI Properties to be "open when called" and "close when finished."

I did something different in the AF project template with the Splash Screen because that pattern of splash screen is useful regardless of your application architecture, and it doesn't have any interaction aspects.

I would also name "Root Actor.lvclass" something else. The term "root actor" is meant to be a descriptor for many different actor classes. I do not want people to think "oh, root actors all have a common ancestor called Root Actor." I would name it for what it is -- like all Actors should be. In this case, something like Calculator Actor would be appropriate (since it uses Add and Multiply as nested actors and that's its main task.

A couple changes to the project file:

a) I would remove the Actor Framework.lvlib from the project and leave it down in Dependencies. Today, you don't need it once you have the first actor in your project, and after LV 2015, you won't even need it then.

b) I would move Launcher.vi out of a virtual folder and make it top-level so people don't go searching for some other VI to run.

I would strongly encourage renaming "Send reply - Multiplication Result Ref() Msg" to be "Multiplication Result Msg". Classes should ALWAYS ALWAYS ALWAYS be named as nouns. Putting "Send" in the name makes any discussion about the class really confusing, and clouds the use of the Send Msg function. I'm not sure what the () are for. What is this... C code? 🙂 Similar change for the other msg classes... "Send request- Multiply Numbers() Msg.lvclass" change to "Multiplication Request Msg.lvclass", etc.



Rafal_Kor
Member
Member
on

This tutorial is awesome! i wasn't looking at revB of it, which was why the question from before. thank you, and thank you again!

AristosQueue (NI)
NI Employee (retired)
on

PS: On the whole "naming of message classes" thing. I suggested the terms "result" and "request" and steered clear of "reply" deliberately... a Reply Msg is a specific class in the AF used for sending synchronous messages. I'd avoid using the term "reply" in anything that wasn't a synchronous message. Just a convention, but a useful one, IMHO.

DMurrayIRL
Member
Member
on

Thank you for the feedback, AQ. I will implement the changes, but I'm swamped with work and RL stuff at the moment, so can't get to it quite yet. Hopefully anyone who works through the tutorial will also read your posts and understand that there are limitations in the code as is (Draft B).

I will just comment on my naming conventions. When I started working with AF I found various example projects to be pretty much unreadable, so I came up with the naming conventions in the tutorial as I found it easier to follow the code (i.e. even my own code was more readable to me).

Also, I'm very interested in the Actor Model, and while I understand that AF is not really designed with the Actor Model in mind, I'm trying to implement my code in such a way that it bears as much resemblence to the Actor Model as possible. So in terms of messaging I just have two basic types, request and replies, where replies consist of (a) an acknowledgement that a request executed successfully, (b) some data that was requested, or (c) a complaint that the request couldn't be carried out. So that's why I use the terms request and reply. The "()" are used in my naming convention to indicate that a request/reply will always have some inputs i.e. at the very least a target actor (i.e. an enqueuer input in the AF terminology). Often a request will have some data as well, and replies will always have some data. I'm also playing around with implementing continuations/customers (using Actor Model terminology), which specify what actor a reply should go to (usually the Caller actor, if I'm following the actor tree configuration that you recommend, but not necessarily in my code).

I will of course update the tutorial with your suggestions though (when I get time, as mentioned), and will use your conventions in any other material I post here. I'm just not convinced yet that I will change my methodology in my own code.

- Derek

AristosQueue (NI)
NI Employee (retired)
on

DMurrayIRL wrote:

I will of course update the tutorial with your suggestions though (when I get time, as mentioned), and will use your conventions in any other material I post here. I'm just not convinced yet that I will change my methodology in my own code.


                   

Understood. And thanks.

davidpcl
Member
Member
on

Just to follow on from my previous comment, it's prompted me to write a blog on using abstract message classes to create a bolt on TCP/IP Interface Actor.

The blog is here :-

http://davidpcl.com/2015/05/14/adding-tcpip-functionality-to-actor-using-abstract-messages-classes/

Or, if you just want to look at the demo then the files are here :-

https://www.dropbox.com/s/jd6kw67j3p7uhzm/TCP%20-%20IP%20Remote%20Control%20Actor.zip?dl=0

Any comments good or bad always welcome.

Dave

David Clark
CLA | CTA
IDEX Biometrics UK Ltd
Hampshire, England
DMurrayIRL
Member
Member
on

Okay - updated document and code published (Issue 1.0, or Version 5 according to the revision control on this page). Thanks to everyone for the feedback.

dpnsw
Member
Member
on

Newbie question/problem.

I have just loaded up the tutorial files and have a problem with Actor.lvclass:Launch Nested Actor & Launch Root Actor(See screenshot at end of post).

I tried just pointing to Actor.lvclass but get this error.

_TwoButton_2015-05-30_11-12-02.png

I have opened the Actor.lvclass in LabVIEW and these 2 VI's don't seem to be there (see pic).

Actor Framework.lvlib on Add-Multiply Actor Project.lvproj_My Computer_2015-05-30_11-11-26.png

Any ideas what is going wrong? Do I need to reinstall something?

Pic of loaded project with errors

Add-Multiply Actor Project.lvproj _ - Project Explorer_2015-05-30_11-10-26.png

Also as a side note if I open the Launch Actor.vi or the Actor.vi from Actor.lvclass they both show up as being broken. Is this expected? I thought it might be because Actor.vi was abstract but it isn't Dynamic Dispatch so I am kind of stumped.

I have loaded some of the files from the NI "Actor Framework Hands-On Instructions" and they don't seem to have any problems.

Is it possible that in removing the Actor Framework.lvlib from the project the example files have wound up with a version issue where an old version of the library had these 2 files and the new version has only 1 more general VI to do both tasks?

Many thanks

David

dpnsw
Member
Member
on

Hi Brainstorms,

Thank you for the reply but unfortunately I am using LV2014. I have tried pointing to the Actor.lvclass from LV 2014-64bit (I am using 32 bit) also LV2013. All show the same error.

The tutorial is looking for both Launch Nested Actor & Launch Root Actor which don't seem to exist in LV2014 so I am guessing the tutorial was actually build around a previous version of LV and/or Actor Framework that had both of these.

The Launcher.vi in the tutorial examples is calling Launch Root Actor.vi which can't be found

and from the Calculator Actor Class

Calculator Actor.lvclass_Actor Core.vi Block Diagram on Add-Multiply Actor Proje_2015-05-30_12-55-47.png

I checked and the update service also claims my LV 2014 is completely up to date.

Is there a version mismatch between the tutorial and the version of Actor Framework that is now in LV2014 & 2013?

Brainstorms
Member
Member
on

David, the version of LabVIEW that the tutorial was built with is 2014, which changed the VIs used to launch actors.  It's possible to modify the tutorial to work with a version earlier than LV 2014...  However, that sort of presupposes that you're aleady sufficiently familiar with AF that you would know how to do this.  Which, of course, presupposes that you're not working the AF tutorial to learn AF...  I guess that's Catch-22.

Otherwise, if you know someone with LV 2014, it's also possible to backport LV 2014 AF to either LV 2013 or LV 2012 -- I've successfully done this.  (The AF code is all LV source code, so you only need to 'Save for prevous version' to do this.)

DMurrayIRL
Member
Member
on

Hi dpnsw - unfortunately I'm not sure how to help you with this. Just to clarify, the tutorial is coded entirely in LV2014 (14.0.1 32-bit, SP1, to be exact). The Actor.lvclass version number is 1.0.0.5 under general settings. I've attached screen shots of both below.

If anyone else is having trouble opening this is LV2014, I'd love to know, so I can try and fix it from my side. I assumed it was ok as I've had no complaints up to now.

So I don't think I can help - I'll leave it to the NI guys (and they don't pop up much here over the weekend, which is understandable).

1 LV Version.jpg

2 Actor.lvclass Version.jpg

dpnsw
Member
Member
on

Hi DLMurrayIRL

That is really helpful. I am on version 1.0.0.1 (source version 12). This must have happened when I installed the NI Linked Network Actor. This then seems to have installed (or did I manage to do this, not sure) version 4.3.0.35 of the Actor Framework. By uninstalling the 4.3.0.35 in VIPM I got the correct version of the file back again and all is well (as it didn't uninstall the Linked Network Actor stuff). Thankyou for the help.

DMurrayIRL
Member
Member
on

OK, great that you got it sorted, and you're welcome.

winston.hensley
Member
Member
on

This was an excellent reference and answered a few questions I had. Could you please elaborate on Figure 2.141? I've seen the "To More Specific Class" function used in the AF but am not sure that I understand why it's used. Also, it seems that creating a class constant generates a new object each time the Addition Result Msg is called, is that correct?

Based on what I've read it looks like the "To More Specific Class" is used in the message to guarantee that an object is of a particular class before allowing it to perform a method. Perhaps this would explain why I've been getting class conflicts when creating new methods/messages using the automated tool.

Thanks in advance!

Fig2_141.jpg

DMurrayIRL
Member
Member
on

Hi - unfortunately I can't give good answers to your questions. In creating 'Do.vi' manually, I just copy what the message maker tool does, without really thinking about what is going on here. There are a couple of comments created when using the message maker tool, but I neglected to include those in the tutorial, which was an oversight on my part.

I expect that Aristos Queue or some of the other NI guys can give the answers you seek though.

AristosQueue (NI)
NI Employee (retired)
on

Winston:

I strongly encourage most users to not look at the autogenerated Do.vi files specifically because they are confusng. We did some things in them to bleed out every drop of performance that we could because we knew the AF would be used in some very demanding situations.

All of the Do VIs want to do some operation on the actor, but they can only act on specific types of actors. Because of limitations of LabVIEW's type system*, the actor object comes in on a generic Actor wire and has to be cast to the specific child class that the messge knows about. This is  practice in OO programming languages called "type testing" where you query an object to see what type it is and do different things based on that type. Normally. type testing is a sign of poorly designed code; normally, I would advise people to use dynamic dispatching instead. But there are some architectures where it is required... and Actor Framework's "double dispatching" is one of those cases. So we have to do this type testing.

Now... here we are going to get into a  very deep aspect of the memory systems of LabVIEW. Bear with me here... there's a few layers, but each layer is pretty straightforward.

The "To More Specific" node has two outputs -- the error cluster and the class object.

  • When the type cast is successful, the output object is the same object that goes into the left input. No copy is made.
  • When the type case is unsuccessful, the output object is the default value of the output type.

Because the output is not always the same as the input, the memory manager has two choices for how to relate the left input wire to the right output wire:

  • The two are not the same memory location; that means that a successful cast must copy the object from the left to the right and an unsuccessful cast just puts a default object on the right wire.
  • The two are the same memory location; that means that a successful cast does nothing, just lets the object flow on through and an unsuccessful cast modifies the object value by deleting the input object and outputting the default object.

The To More Specific node uses the second option. This produces the best memory performance for the 90% use case of this function -- casting an object when you already expect the type of object that is coming in.

Unfortunately, that second strategy marks the left side input as a "stomper" -- meaning that the memory location is one that could be modified by the downstream node, so upstream sources have to make a copy if they fork the wire. We HAVE to fork the wire because if a message's cast fails, we need to keep the original actor object. But we wanted to avoid copies of objects as much as possible because actor objects could have quite a lot of state in them and making a copy of the actor every time it got a messge would be a huge burden on the system (and quite possibly make it impossible to use on real-time systems).

When the right side output of the To More Specific node is UNwired, there is no need to mark the input as a stomper... the node only reads the object, it never modifies it.

So this is why we have two To More Specific nodes:

  1. The first node just checks the type. It does so in a way that does not cause us to have to make a copy of the actor object.
  2. We then go into the case structure. In the error frame, the actor passes through unmodified. In the no error frame, we have a second To More Specific node. This one performs the type check a second time, but this time, we know the check will succeed, so, again, no copy is made of the incoming object.

Voila! Nearly efficient code. The only waste is the double performance of the type check. I hope in the future that I can get my compiler team to optimize this case so that the compiler recognizes this pattern and just skips the second type check. I hope in the longer future to eliminate the need for this pattern entirely by making the actors and their relationships to messages a formal part of the LV language, which would allow us to type check in the compiler before you ever start running that only valid messages are being sent to a given actor's enqueuer. This is possible (I've worked out the details and seen supporting work in various academic papers) but requires a more sophisticated type system than most programming languages support (so I don't have an existing model to just copy).

Does that make sense?

winston.hensley
Member
Member
on

DMurrayIRL thank you for your response, I'll stop beating myself up for the

lack of understanding now 😃

Aristos Queue - That was an excellent explanation and it makes much more

sense. Prior to your explanation, I had a very erroneous understanding of

why the 'To More Specific' function was being used.

Andrew.D.Owens
Member
Member
on

Excellent demo and support document!  I think getting used to the functionality that comes with the native actor framework (lib) versus what functionaity the user adds is a key distinction to illustrate.

Amiri
Member
Member
on

Is this AF class going to be available as an online course soon?

Amiri
Member
Member
on

Wow, thank you DMurrayIRL for the great demo and documentation and attention to detail!  I can tell you put a lot of effort into it. At first, I cringed at the 154 page count on the tutorial, but it goes pretty quick as a lot of those pages are screenshots and not tons of text.

I have peaked into the Actor Framework rabbit hole multiple times since hearing about AF and this past week decided to jump in, yes, I just spent about a week in the Actor Framework Ultimate Experience (AFUE) …I was seeing purple class wires spiraling up into the sky and wrapping around my brain…following every link, reading every post and cross post, videos, descriptions, etc and finally finishing up with this demo – when I finally came out of this ultimate experience I had successfully* completed this AF demo, and have a slightly better understanding of how it works, but still have some questions. 

Questions:

  1. *When I press Stop, what VI’s are still running in memory?  I cannot find them, but the classes remain locked and I cannot close the original UI (Actor Core from Framework Override), however, the clone closes just fine.
  2. Before creating do.vi (for override) – In the Error list Details section it says “This VI’s owning library has some problem.  The library has blocked the VIs that it owns from executing until the problem is resolved.  Please see errors listed on the library.”  How do I find the “Errors listed on the library”? 
    1. I understand why it breaks; however, is there a place where I can get more specific detail on the error?  I’d like to see something like…”you need to override do.vi…”
  3. What would happen if I were to turn off the reentrant behavior of my Actor Core (framework override) do?  Would that even make sense with this AF framework?
  4. I see notes in most of the Actor Framework.lvlib that the developer should do a “Save As…” if they choose to modify those files…how often are developers modifying the library and why do they need to? (I may be getting ahead of myself, trying to run before I can walk, but I can’t help but wonder…)

Regards,

Amiri

AristosQueue (NI)
NI Employee (retired)
on

I'll leave question 1 for someone who knows this specific example.

Amiri wrote:

2. Before creating do.vi (for override) – In the Error list Details section it says “This VI’s owning library has some problem.  The library has blocked the VIs that it owns from executing until the problem is resolved.  Please see errors listed on the library.”  How do I find the “Errors listed on the library”? 

Right click on the library in the Project Tree and choose "Show Error List Window."

Amiri wrote:

3. What would happen if I were to turn off the reentrant behavior of my Actor Core (framework override) do?  Would that even make sense with this AF framework?


                   

No two actors would be able to handle the same message at the same time. So, for example, if you send Stop to five nested actors at the same time, they would have to stop serially instead of in parallel, increasing the thread friction.

Amiri wrote:

4. I see notes in most of the Actor Framework.lvlib that the developer should do a “Save As…” if they choose to modify those files…how often are developers modifying the library and why do they need to? (I may be getting ahead of myself, trying to run before I can walk, but I can’t help but wonder…)


                   

They modify it because the AF has been developed by me but in strong partnership with a wide swath of the community. Some people have found bugs and fixed them, verified the fix, and sent it to me to integrate into the shipping code. Others have found ways to boost performance. Others have prototyped new features I never thought of. And still others just don't like the names\icons that I gave to types\methods\terminals. 🙂

Contributors