Published December 6, 2015
Now that we understand the concepts and building blocks of the Actor Framework, lets learn how to actually run some code.
- Actor Framework Basics: Part 1 - The Basics
- Actor Framework Basics: Part 2 - The Actor
- Actor Framework Basics: Part 3 - Launching and Communicating
- Actor Framework Basics: Part 4 - Being Productive With Actors
- Actor Framework Basics: Walkthrough - Creating a Logger Actor
Launching an actor is the process of starting up the message handling loop of the actor. When an actor is launched a new thread is created (or a VI run asynchronously in LabVIEW-speak) and the message queue references are created. An important concept when working with actors is that actors can launch more actors. The first actor in the chain is known as the Root Level Actor. A root level actor may launch another actor known as a Nested Actor. A nested actor can launch more nested actors.
Notice how all threads are created as need. This means that we don’t have to decide at design time how many or what kind of actors to launch. Your program can wait until the user clicks a button, or a DAQ value is read, or any other condition is met, then launch an appropriate actor to handle it. This is extremely powerful when creating highly dynamic applications. When you launch an actor you’ll get a reference to it’s Message Enqueuer. This is what you’ll use to send messages to your actor.
Once the actor has been launched you can send messages to it. You do this using the Enqueue method of the Message Enqueuer class. If you’re using the scripting tools (which you most definitely should be) methods to help you send messages will be scripted for you. These will make sure all of your messages contain the correct data and the message class is correctly constructed. Actors can easily send themselves messages. They just need a reference to their own message queue. They can get that using the “Read Self Enqueuer” Actor Method.
Once you’re done with your actor you need to tell it to stop. Built into the framework are the Stop and Emergency Stop messages, either of these will cause the message handler loop to stop.
When an actor launches a nested actor it will almost always also want to send messages to it. It can do that easily using the message queue reference that it gets when the actor is launched. It is often useful for a nested actor to send a message back up the chain. You can get your calling actor’s messaging queue using the “Read Caller Enqueuer” Actor method.
Most of the time this is how the communication between actors works, the Root Actor is talking to it’s nested actors. Those nested actors talk to their nested actors, etc. You end up getting this sort of pyramid shape of actors running. It’s possible for actors to communicate directly with actors not above or below it in the pyramid, but you (as implementer of all of the actors) are responsible for passing around the message enqueuer reference as needed to make this happen.
You should now begin to see the power of the framework. We can design each actor to be a small, well defined, easily testable piece of code. Then we can create another actor that launches our small actors, and another actor above that that launches that actor… until we have a very complex system. The only problem is you have a lot of loops running all messaging each other. It’s easy to get into a “wait, whats actually running right now?” situation. Well I got tired of this, so I built a tool to help. See our post on Monitoring Actors for information about the tool. The tool gives you a visual representation of the entire system as it’s running. It shows you which actors are running and who’s the caller of who. It also give you tools to help debug them.