Menu

Tag Archives: Actor Framework

As anyone who has read my blog previously, you will know that I am a big fan of Actor Framework. It is a fantastic way of creating highly robust and scalable asynchronous process applications.

Having said all that, my biggest reservation about Actor has always been that because of the way the messaging between Actors works, out of the box Actors are strongly coupled. In a lot, maybe most instances this is not an issue as you may be putting together an application whereby the different Actors benefit from being strongly coupled or there is no benefit to decoupling them, but I’ve also come across a few use cases where I want to be able to completely decouple individual Actors for testing, and to allow multiple people to work on the same application.

One solution to this is abstract message classes, and one of the places where I’ve found this comes in really useful is adding a TCP/IP socket onto an existing Actor.

Initially this came from working on a project where I’d created a no abstract messages TCP/IP Actor, but then another project came along that also required TCP/IP control so I refactored my TCP/IP Actor with abstract messages to re-use it.

How this worked in practice is that in the original coupled TCP/IP Actor to communicate with its caller, I enqueued two messages to report the TCP/IP Actors status in terms of clients connected, and also to communicate messages received to the caller. The caller was then able to ‘Do’ these messages, and enqueue a message on the TCP/IP Actor to communicate back to a client.

The process to convert a non-abstract message to abstract is fairly straightforward using the following process:-

Create your message as usual using the Actor Framework Message Maker

Remove the ‘Do’ and ‘Send’ methods from the Message Class.

In the class properties, under the ‘Inheritiance’ Category, check ‘Transfer all Must Override requirements to descendant classes’.

To understand why you need to do this, open Message.lvclass from the ActorFramework directory under vi.lib. Under Item Settings in the class properties, if you select ‘Do.vi’ you will notice that the checkbox ‘Require descendant classes to override this dynamic dispatch VI’ is checked. This forces any classes that inherit from Message.lvclass to have to implement this method, by using ‘Transfer all Must Override requirements to descendant classes’ it removes this requirement from the class you are inheriting into, but pushes the requirement down to any child classes of itself and allows the class to compile.

Next you need to expose any properties of the Abstract Message, as we no longer have a send method to encapsulate these (although there’s no reason why you couldn’t create a new one and pass in the class type) so we will have to set them via property nodes and will use the Enqueue.vi directly.

Because the Do method has been removed, if the TCP/IP Actor wants to send the message to its caller, there won’t be anything to execute, so now you have to create a message class that inherits from the abstract class and create an instance of the Do method. This will be specific for the particular caller Actor you want to use it with.

Now you’ve inherited these Concrete classes from the Abstract classes, you now need to tell the TCP/IP Actor to use these classes at runtime, I personally tend to do this using a Constructor and passing in the concrete classes to be held in private data.

This means that now, when you want to send what was originally a specific caller message, you now have to pull what class the caller specified to use out of private data, populate its properties and enqueue it on the callers message queue.

You obviously also need to go back to your new Concrete classes and populate their Do methods for anything to happen.

Exploring the demo

If you follow the link below, you can find a zip file of a TCP – IP Test Actor, interfacing to my abstract TCP/IP Actor with abstract messages.

Start by running Main.vi from TCP – IP Test Actor.lvlib to bring up the Test Actor.

Then run Main.vi from TCP – IP Client GUI Actor.lvlib.

On the TCP – IP Client GUI the available commands are populated from TCP – IP Remote Control Actor\TCP – IP Client GUI Actor and are in a tsv format.

From the Remote Client GUI you should first of all click ‘Open’ to begin a session with the TCP – IP Remote Actor. You should notice that as well as the light on the Remote Client GUI lighting up, you should also see the Connections light on the TCP – IP Test Actor GUI also light up, and the No. Clients indicator show 1. NOTE: you can now open up another Remote Client GUI and do the same again, and this should increment to 2.

Now a session is open, you can select commands from the pulldown, and populate the parameters and these will update those on the TCP IP Test Actor, or alternatively if you use the GetNumeric, it will return the value of the Numeric Indicator.

The key to all of this working is the TCP – IP Test Actor.lvclass:Handle Remote Command.vi. This is called from the Do method of the Concrete class Remote Command handler MSG.lvclass, and there is an equivalent VI called from the Do method of Remote Connection Status Msg.lvclass.

You will also find a VI called ‘Basic Example.vi’ under TCP – IP Remote Control Actor.lvlib\Test that demonstrates how to make single writes to the remote actor.

There’s probably not much more to add so please have an explore of the code, and message me if you have any questions, problems, or recommendations. Feel free to re-use any parts of this demo, as by design you should be able to pick up the client GUI and remote control Actor and attach it to any of your own Actors, but please remember give me credit if you do 🙂 Thanks, Dave.

I’ve had an interesting problem to solve at work this week involving creating, buffering, and then transmitting GPS signals using an NI RFSG but being able to alter those signals on the fly.

For the project as a whole we committed to using the Actor Framework early on as it is quite a complex asynchronous process application with significant inter-process communication with a strong requirement to be able to chop and change modules as well as adding new ones in at run time.

This admittedly could also be done using daemons, but the benefits of Actor such as the robust inter-communication, ease and speed of putting an infrastructure in place and the ability to very easily make an Actor Framework remote controllable and run headless via TCP/IP (which is a very common request from clients) made it a perfect fit for this job.

However, this particular problem also had state machine written all over it, and having tried to use Actor before to do state machines where you have a different VI for each state I have found that they very quickly become very difficult to debug and follow so I thought I’d have a crack at putting together something that would provide all the benefits of Actor and a single VI with a state machine and this is a demo I came up with to prove the design.

It is certainly not the most inspired demo you will ever see, it is simply an overridden Actor Core GUI with a FSM running behind it that simply cycles through states to set 4 colour boxes on the GUI and allow you to start/stop the cycling, and change the interval between each box being set.

GUI

On the GUI We have a State indicator which is set from the state machine itself and a Play, Stop, Reset Button, and FSM Interval(ms) control that trigger events in the Actor Core override and enqueue message handlers to be executed on the core.

Actor Core Override

Project

Actor Private Data

The FSM itself is a single VI that holds its state information in the Actor private data and simply iterates from an idle state to 4 states which set the colour of each color box with a one iteration delay between each.

Actor FSM

Now the cool bit, and one of the reasons I really like Actor. To run this as a state machine you use the Time-Delayed Send Message.vi to instruct the Actor Core to enqueue the state machine at certain intervals.

There are actually two ways you can do this, you can use the Time-Delayed Send Message.vi with the iterations option set to to 0 – this will enqueue the state machine at a set frequency ad-infinitum which is great, but I personally prefer the option to use Time-Delayed Send Message.vi with the iterations option set to 1 which means it will do a single enqueue of the specified message with a time delay which I do once in the overriden Actor Core to get the process started, and then at the end of every iteration of the FSM.

My main reason for this preference are primarly debug; If you use the infinite enqueue option (0) and you run the vi that is being enqueued with execution highlighting switched on, messages do not stop getting en-queued in the background so as soon as you turn off highlighting all those messages that have been en-queued will get executed one after another without any delay.

Another reason for my preference is that by en-queuing on each iteration it also means that you can alter you interval rate, so for instance when the state machine is in IDLE I enqueue an element with a delay of 1 second, then when the play button is pressed the interval is set from the from panel FSM Interval control – it is a neat little feature that I can think of many uses for i.e. the classic CLD car wash exam where you have to time each state using an elapsed time vi – well here you could simply use constants for going between states. I have also used Time-Delayed Send Message.vi quite extensively for data logging use cases where i have found it’s time to be remarkably accurate.

FSM State Enqueuer

In terms of the event handlers, well they simply set the next state of the FSM (but could obviously do a lot more) – another really nice feature of Actor in this context is that because all messages are executed in-line with the FSM it makes it very easy to debug and integrate user events with the state machine – although one thing to watch out for here is that if you are putting very small or possibly no delays between your FSM being en-queued for execution, it is worth giving you Event Handler messages high priority to ensure they always get executed as soon as an iteration of the FSM has finished or before if it is in a delayed state.

Play event handler.

Link below for project – possibly obvious, but run Main.vi to get started – LabVIEW 2013.