Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How to create reply message on request

Could you tell me how to create reply message on the request message from another Actor.

I have cylinder actor and the cylinder should simply report its state (Busy, Error) to the process that called it (send request). I want create abstract message for it. I don't know what I must create in my Actor 😞

Please help me 😉

Thank you.

-- Peter --

0 Kudos
Message 1 of 33
(7,711 Views)

There's no automated way to make reply messages. Here's the steps you go through:

  1. Ask yourself, "Am I really absolutely sure I need a synchronous reply message in this project?" If the answer is "no," then abandon this and go create a good asynchronous message using the usual tools.
  2. Add "Reply Msg.lvclass" to your project -- it is not a required part of the Actor Framework, so it has to be added to your project separately.
  3. On your project target, right click and choose New >> Class.
  4. Name the class "XYZ Reply Msg" where XYZ is whatever name you want to give it. Actually, you could name it whatever you want... this is just my naming convention so everyone knows "this is a reply msg" --- it is dangerous (causes deadlocks) to add these to an AF project without considering all the other reply messages in the system, so it is important to know where they all are at a glance.
  5. On the new class, popup and choose Properties. Set the new class to inherit from "Actor Framework:Reply Msg". Hit OK to close the dialog.
  6. Open the private data control of your message class. Add any data that you want this message to carry.
  7. On the class, popup and choose New >> VI For Override. Override the "Do Core.vi".
  8. In your new VI, use the To More Specific node to cast the "Actor in" as the receiver actor type -- you can look at any other message class Do.vi to see an example of how to do this with minimal data copies... it's admittedly a bit awkward, but it works.
  9. In the case where the To More Specific succeeds, add your code. Use the data fields stored inside the message and any methods available on your receiver actor class. The value that you want to send back to the sender should be placed in the "Reply" terminal as a variant.
  10. Popup on your message class and choose "New >> VI". Give this VI an output of your message class type. Give it inputs for all of the private data control fields. Save this VI as "Init.vi" or something like that.
  11. Save your class.
  12. Now in your sender, drop the Init.vi that you created. Wire the class output of that VI to the input of the "Send Message And Wait For Response.vi" found in the palettes. You have now created a message that will cause the sender to pause and wait for a reply.

Now that you have done all this, stop and ask yourself AGAIN, "Am I REALLY sure this is a good idea? Am I absolutely sure that I cannot do this by sending a message to the receiver and then letting the receiver send a message back to the sender in its own time? Do I HAVE to create a synchronous reply message?" These wait-for-reply messages are dangerous, as I said above. You can read about them in many places on this forum and in the help for the Actor Framework that ships with LabVIEW.

Message 2 of 33
(6,399 Views)

To have asynchronous messaging and still get the replies you need, what is usually done is registering and broadcasting.

That means that the controller sends a message to the cylinder: "Register me for updates" with its own queue ref; cylinder keeps an array of actor queue refs that need to be updated; every time cylinder state changes, cylinder sends a "State changed" message to all the refs in the array. The controlling process can also choose to unregister and then cylinder removes its ref from the array. This way the controlling process knows the state of the cylinder at all times without locking the system with a reply message.

Good luck!

Danielle

"Wisdom comes from experience. Experience is often a result of lack of wisdom.”
― Terry Pratchett
Message 3 of 33
(6,399 Views)

In addition to the “Register-Notify” setup Danielle describes, one can also do an asynchronous “Request-Reply”, where the Request message contains the enqueuer of the sending Actor, and the Reply is sent as part of the “Do” method of the Request.  This differs from the “Reply Msg.lvclass” that AQ described, in that the requesting Actor is not blocked waiting on the Reply.

Message 4 of 33
(6,399 Views)

Thak You 😉

0 Kudos
Message 5 of 33
(6,399 Views)

So I realize that this is an old thread, but I have a question that seems very much related to this desire to have synchronous behavior with reply messages in an otherwise AF project.

 

I've got many projects which are testing a DUT -- think change a setting, then take a measurement. There might be 10s to 100s of such synchronous behavior built in to the test. However, simultaneously there is a desired to have the UI keep displaying the current measurements, create graphs, save data, etc. so it seem the project is mixed between asynchronous and synchronous. To have both asynchronous and synchronous, I was also (like the OP) thinking of using AF but with reply messages built in. 

 

However, I was wondering about a second scheme - namely some kind of state behavior embedded in Root actor. For example, I first change my root actor state to "test mode" and send an async request to change a setting -- then based on the state being "test mode" when I receive the setting message back I send a second async request to take a measurement. When that measurement async message comes back, I record the setting and the measurement in the private data of root.

 

How should I consider the choice: (1) relying on reply messages (risk of deadlocking) or (2) state behavior? I'm not sure how to navigate this decision.


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 6 of 33
(3,374 Views)

I'd be tempted to try and write just one message for the situation you described, in which the action to be taken is "change a setting AND take a measurement, and then at your convenience send me an asynchronous message with the result".

 

A key part here would be that when the scheduler/root actor receives a result, it needs to know what test it is a result for, so you'd have to include that information in some manner in the non-Reply-Msg 'reply'.

 

A potential difficulty comes when you have many different settings, and many different tests - creating a message to send to your nested "test-do-er" Actor would be presumably prohibitive.

 

In this case, consider if you can create a class (or perhaps a cluster is sufficient) that represents all of the settings for the "do-er" (I'm going to write B next time...). B can then compare the new settings with the current settings, and only change the ones that are not the same (unless it is simpler and not terribly slower to just update all the settings every time, some hardware this is the case).

 

Then all that remains is to identify the test, an enum can manage this probably, although it might not be the most extensible if you are frequently adding new tests.

 

In that case, you could instead consider a class which has space for a result in the private data. B then runs the test, fills in the result to the object it received, and then sends the object back to the root actor (asynchronously). The root actor then knows which test it represents, especially if you include an "ID" field or similar in the data object.

 

Edit: I also note on re-reading the thread, that this is a rather more verbose explanation of what drjdpowell wrote in 2015. If you prefer videos to text, then he has several available, at least one of which covers the Request/Reply setup he describes (although for his Messenger Library, not Actor Framework, but the idea is close enough for it to be helpful here in my opinion).


GCentral
0 Kudos
Message 7 of 33
(3,362 Views)

Thanks for the reply! I realized after reading your reply multiple times, and my original question that I left out a key detail. Namely that "change a setting" and "take a measurement" will likely be undertaken by different actors. So the problem is getting multiple actors to do things synchronously.

 

That detail (my mistake for not including it) seems to modify the structure significantly and preclude me from pursuing your first suggestion, right?


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 8 of 33
(3,350 Views)

@WavePacket wrote:

Thanks for the reply! I realized after reading your reply multiple times, and my original question that I left out a key detail. Namely that "change a setting" and "take a measurement" will likely be undertaken by different actors.


Hmm, that does make it more difficult. Is the different actors bit a hard requirement for some other reason?

 

You might have some better luck if you can avoid making the "make a measurement" actor an Actor - does it need to run asynchronously and hold state? If not, a simpler by-value class might be easier to handle, since then synchronous operation is more easy to reason about. This becomes problematic if lots of different things need to use it, but if that isn't the case I'd recommend considering it.

 

Otherwise you're stuck with either the use of Reply messages (at least from the setting actor to the measurement actor), or some confirmation via timestamps of the active set of settings, which would be tricky to be sure of. There might be better solutions, if I think of one I'll post again although probably someone else will post to correct me first 😉 


GCentral
0 Kudos
Message 9 of 33
(3,344 Views)

Yeah, I was hoping to "live stream" measurements (actor controlling hardware) of a DUT (second actor controlling separate hardware) up to the user interface in the background, so I was presuming this would be best handled by AF.

 

Currently it seems then that the best way forward for me is synchronous reply messages in AF, which I realize that many people have caution away from. However, I don't see a better way forward right now...might be my ignorance. 


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 10 of 33
(3,340 Views)