Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

I don't understand how to code without blocking calls


@Thomas_robertson wrote:

Instrument 1 - A QMH which on initialization tells the display manager actor to launch X display windows with such and such settings.   When the user "saves" the settings for Instrument 1, the instrument needs to query the display manager for the current settings.  On Exit it does a last query for the display settings and saves them to disk with it's other settings until the instrument is launched again.

 

Instrument 2, 3, 4, ... - Other instances of the QMH 

 

Display - An Actor or QMH (different displays are Actors or QMH's depending on when they were refactored last) which contains its own state and which the user can interact with to change how the display presents data and even what data is presents.   Has it's own block call mechanism which it uses to respond to the display manager when queried for its settings 

 

Display Manager Actor - An entity which receives messages to open and close Displays, does so, and keeps track of their enquers or other communication mechanisms (queues in the case of QMH's).   Receives blocking requests to get settings from open Displays, then it in turn sends a blocking request to each display for their settings, Bundles all this information up and returns it to the requester (i.e. Instrument 1, 2, 3 ...  in this scenario).


Move the saving behavior into the Display Manager Action engine. Let it handle that responsibility.

This goes along with what Dr. Powell said about making it a shared resource, just instead of a shared actor make it an action engine. If every call to it is going to be blocking, then it doesn't need to be an actor. Making it an actor adds no value just complication.

 

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 11 of 15
(691 Views)

@BertMcMahan wrote:

@Thomas_robertson wrote:

Really?  It's considered ok to make block calls to Actors as long as those Actors aren't making calls back to you?   That's considered acceptable design?   This is the first time I've read such a thing, I thought everything I've read was clear that block calls are always and forever a code smell that should be eliminated.


I don't think he meant blocking calls to Actors, just blocking calls to a shared resource.

 

Does the manager need to be an Actor, or can it just be a by-ref Object? If you have a regular ol' by-ref singleton object* then you can distribute it to everything that needs it. It sounds like you might not need this display manager to actually send and receive messages.

 

Or, you could still have your display manager send and receive messages, but it operates on a by-ref "Display storage object" that's shared among your other Actors.

 

*Singletons and by-ref objects aren't the normal paradigm in LabVIEW. Normally, you use by-value objects, meaning when you create one and split the wire, now you have two. With a by-ref object, you instantiate it once using a DVR (for example) to hold the data. Then when you split the wire, you're duplicating the reference instead of the data. Then everything that needs to operate on the object itself can use blocking calls on your shared resource. This is the way that lots of shared resources are handled (e.g., serial ports using VISA)


I should have read further down before responding. This is exactly along my lines of thinking - although I was thinking Action Engine instead of refwire, but if you don't mind passing references everywhere this also works.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 12 of 15
(689 Views)

@Taggart wrote:

This goes along with what Dr. Powell said about making it a shared resource, just instead of a shared actor make it an action engine. If every call to it is going to be blocking, then it doesn't need to be an actor. Making it an actor adds no value just complication.

 


This right here- I think a lot of people fall into the trap of "well if an object is good, then an actor is better". An actor doesn't replace objects; it replaces asynchronous message handlers. Don't make something an actor unless it needs to handle messages in some way or needs to behave asynchronously.

 

Spoiler
I can't find the reference now, but AristosQueue had a post where even he mentioned he got carried away trying to make sure an Actor call was blocking, and was needing to place his code in Pre-launch init since it was non-reentrant. Then he realized wait... I just need a regular non-reentrant VI 🙂

@Taggart wrote:

I was thinking Action Engine instead of refwire, but if you don't mind passing references everywhere this also works.


I mentioned refwires since I've found I sometimes DO need to duplicate a resource. For example, I might need a single instance of an internal "database" object that holds some information (e.g., settings) that can be used anywhere inside a single Actor, but would need to be duplicated for each Actor clone I spawn. An Action Engine is much simpler to use, but can literally be used for ONE single resource everywhere in your code. It's great for things like a serial port or a physical hardware resource. Horses for courses, I suppose.

0 Kudos
Message 13 of 15
(674 Views)

Keeping with the 'Actor' and 'Resource' jargon used in this thread...

 

Two rules of thumb I use to decide whether an entity needs to be an Actor:

  • Does it need to monitor its state and alert 'others' (basically, triggering events without being asked)
  • Does it take 'too long' to produce a response to a request (basically, is this entity blocking its upstream caller adversely, even if the response is an error)

If at least one 'yes' answer is noted, then I make it an Actor. Else, I prefer to use it as a resource.

 

Oh well, Bert wrote it succinctly, and beat me to it. 😀

Message 14 of 15
(672 Views)

I gather from the discussion that you guys think of AF Actors being more complex to use than Action Engines (or by-ref Objects).  I find with Messenger Library that my actors are just as easy, while being more capable, and never use Action Engines and rarely use by-ref Objects.  I have often used actors as shared resources.  Even if you think you only need blocking calls on a resource, you will often find a value in some async stuff as the project develops.

0 Kudos
Message 15 of 15
(653 Views)