Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Saving settings for actor framework application

Hi all

I am (starting to) develop an application in the Actor Framework (AF) in which most actors have some form of settings (ip address to communicate to, a sample rate, etc.).

These "settings" I keep as private data in the Actors. For example actor responsible for saving log messages to disk, lets call it Logger, will have a private data member called "LogFilePath". If the setting is user changable (via a GUI) the actor will have an method to write that property, e.g. WriteLogFilePath which can be activated using a message called SendWriteLogFilePath.

What I wonder about is how I should save those "settings" from program launch to program launch. They obviously have to be written to disk somehow - stored in a file for example.

I would like to not duplicate functionality so I would prefer to have an actor handle the interacitons with such a settings file, lets call it SettingsManager. It should have methods to write settings to the file, change them and read them back. But how should the settings get to and from the SettingsManager?

All actors having settings could inherit from a common actor wich provides them with the enqueuer for the SettingsManager. That way they can easily involke the method SaveSetting by sending the message SendSaveSetting.

But what about getting settings from the settings manager? The LoadSetting-method could take an enqueuer to use for replying as argument. As a text language analogy LoadSetting(string setting, enqueuer reply_enq). But that would cause all actors to have methods for receiving settings. That would couple the actors and the SettingsManager more strongly.

What do you guys do?

/ JonasCJ

0 Kudos
Message 1 of 4
(4,496 Views)

The loosest coupling I can think would be if messages could return a value such that you could call LoadSettings and use the result (e.g. wire the output/return value directly to the actors internal SendChangeSomeSetting message which would then take care of updating the private data).

Then the actor making use of the SettingsManager would not require to implement any method for receiving the answer from the SettingsManager.

This would of course be a blocking operation, askering for something and waiting until the answer arrives, but that is okay in this case because the actor cannot do anything meaningful before it receives the answer. It would probably like to obtain its settings during PreLaunchInit...

0 Kudos
Message 2 of 4
(3,528 Views)

The main solution I use is to create a generic object with some type of name/value pair storage mechanism. Object would provide the following methods:

[Public]

Set Parameter (name [string], value [string  | variant | polymorphic data type]

Get Parameter (name [string], value [string | variant | polymorphic data type in / value out]

[Protected or Community]

Constructor (Actor name [string])

Save [INI, XML, object directly to file (not recommended)]

Load [INI, XML, object directly from file (not recommended)]

Each actor would receive a message (Configure) with an object that relates to the Actor being configured. The Actor would query it’s parameters on receiving the message and take any actions to setup it’s state. Or set the object just before calling Launch actor in a Launch Actor wrapper vi.

I would create an abstract actor and implement Configure (dynamic dispatch must override) or Launch Actor Wrapper (static dispatch) and Save (dynamic dispatch must override). Create Messages for Configure and Save at the abstract actor level so that there are only two message Classes for all actors that can be configured. Each child actor of the abstract actor will need to implement the must overrides and provide specific functionality. The abstract actor will inherit from Actor.lvclass but will not have an Actor CORE.vi since this will be handed by the more specific actor types.

If you go the route of Launch Actor Wrapper, input the configuration object and set the object in the abstract actor’s class wire and provide a property (read only) to read the object from the more specific actors.

For the specific configurable actors, the actor can then either, store all parameters in the configuration object (could be performance hit based on implementation) or store all parameters in Actors Class wire.

When Actor receives (Save) message (Reply message), the actor will return the object with name/value pairs set to the controlling actor. The controlling actor will have access to the Save/Load functions, however, other actors will not. The load/save will create or read sections from a file. The constructor will set the name of the configuration object based on the Actor’s name (if you plan to launch multiple copies of the same actor you may need to use some other identification means.

If you intend to make the storage class dynamic dispatch for any reason, then polymorphic instances will not work.

I have never had a need to create child object of a configuration.

Again, this is how I’ve done it and it works, these are merely suggestions please prototype and implement as your system needs. Just remember K.I.S.S is usually best. The more complicated the more difficult it will be to adjust later.

I'm not 100% concerned about performance during a load or save, these operations tend to be infrequent and so don't have to happen at light speed. But you may need to make adjustments. There's also the AQ Character Lineator that may help you out. My method above may not fit with AQ Character Lineator.

Brian G. Shea
Certified LabVIEW Architect
0 Kudos
Message 3 of 4
(3,528 Views)

Hi Jonas,

I don't know if get this right but it sounds to me like you've a little twist in your thoughts

JonasCJ wrote:

All actors having settings could inherit from a common actor wich provides them with the enqueuer for the SettingsManager.

Please remember each started Actor needs be provided with the Setting enqueuer. It's just the structure of the private data, which is shared along the inheritance, not the information in it.

My solution for saving settings is kind of similar to Brian's but also different. I made an abstract message called configuration. This message child adds methods to load/save the object as xml. This message is paired with an abstract actor, which has the application\save-settings path in its private data. Now the do.vi is getting the save path from the actor and calls its save.vi if no error. This way each time the actor gets the message it's saved. Of course I expect configuration message to be sent rarely, so that this shouldn't cause a performance issue.

Now if I want to create a configuration, I create a vi to apply the settings, I use the Message Maker to create a message from it, I change the inheritance to my configuration message and change the do.vi so that it calls its parent method after the execution of the apply vi. This way I make sure that the settings are only saved, when they have been applied without error.

To recover the last configuration state, the actor loads the xml file before lunching the core, unflattens it to configuration messages, writes data into front panel elements and sends the configurations to its core to apply it. This causes a little overhead, since it saves the config it just loaded, but I found this the easiest way to do it.

I also have another approach, where the configuration is not just saved each time it's applied, but also as set of current state to recover it later. Let's say I want to repeat a measurement, but have changed the settings in between. For that my abstract configured actor saves all configuration messages in his private data. I used a variant and the configuration class name for it, so that I have a copy of each applied configuration. Now the configured actor has a save current configurations message with a save path as data, so that my application can save the actor's current config together with the measurements. Corresponding the actor also has a load message to load the configrations from the measurement path.

I hope you can get some ideas from it.

Cheers,

Mike

0 Kudos
Message 4 of 4
(3,528 Views)